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. 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
- 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
- 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
- "Find nearby place name" which provides:
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 |
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.
Improved Map Search
The mouse modes definitons found in libkmap:
- Pan Mode = Map can be panned and zoomed. All the existing thumbnails are displayed on the map. When the user clicks on a thumbnail nothing happens.
- Selection Mode = The selection is made by drawing a rectangle on the map. The thumbnails outside the selection aren't displayed anymore on the map. The selection rectangle from the last search is displayed on the map when the user is not in Pan Mode. To remove the current selection, the "Remove current selection" button must be pressed.
- Zooming Mode = When the user clicks a group of thumbnails, the map is zoomed until it fits to display the most of them.
- Filter Mode = When the user clicks a group of thumbnails/a thumbnail, the rest of thumbnails on the map dissapear. To remove the current filter, the "Remove current filter" button must be pressed.
- Select Thumbnail Mode = When a selection is made, the user can select the images in the central view by clicking on the thumbnails on the map.
TODO Before 2.0
Component | Job | Status |
---|---|---|
Unknown | Size hint of GPS properties tab too wide, workaround implemented: Move KComboBox into a new line. | FOR NOW |
KMap | A border of 0.001 around the images is better now, and should be sufficient for most cases | |
Digikam and KMap | Make the map and the marker models to proper react to setActive function | test again |
Digikam | Make the unfiltered thumbnails displayed transparently when the filtering happens inside a selection | later |
KMap | Save the current mouse mode to the settings. | |
Digikam | Check whether the last active gps search album is properly restored after a restart: Selection rectangle, selection in the search list, display of the thumbnails on the map and in the center view. | Started GV |
Digikam | GPSSearch: Add a "sticky" button or KMap configuration menu item. When sticky is not set, the map can move to show the currently selected search region rectangle. | |
Digikam | GPS Properties tab: Also add a "sticky" button/menu entry. When it is not set, the map should center on the images displayed on the map. | PARTIALLY |
Digikam | Center map view: Also add a "sticky" button/menu entry. When it is not set, the map should also center on the displayed images. | |
KMap | Check whether the zoom levels of Google Maps and Marble are roughly the same when switching between the two backends. | |
Digikam/KMap | Zooming into a group of thumbnails does not work in the properties tab. | Started GV |
GPSSync | Add a way to cancel RG. When calling slotSetUIEnabled, a pointer and a slot can be given which will be called when the cancel button is clicked. | Done MH |
GPSSync | test_gpsrgparsing fails | |
GPSSync | RG: New action: Remove all spacers | |
GPSSync | RG: Model: Handle removal of tags in the source model. SimpleTreeModel first needs to be updated to support removal of items. | |
GPSSync | Handle threads properly when closing while a thread is running, for example when GPX files are being loaded. | |
KMap | The Marble people are implementing a new 'geodetic search rectangle' - find out what that means and port the code over to libkmap for now if appropriate. | |
KMap | Try again to make panning work when clicking on thumbnails in Google Maps. | |
KMap | Implement the new sort-best-items-on-adding idea. | |
GPSSync | Search: options for language selection if appropriate. | |
GPSSync | Search: restrict the search to the visible map area. | |
GPSSync | Search: cancel and progress | |
GPSSync | Search: pressing 'enter' in the search text field triggers both the search and the apply button | |
GPSSync | Add a configuration dialog, like in digikam maybe. | STARTED |
GPSSync | Configuration: Options for units: speed, coordinates, height | |
GPSSync | Find out whether KDE has settings for selecting KM/H vs. miles/hour and make this the default for the speed. Same for the height. | |
GPSSync | Configuration: Whether non-coordinate data should be cleared when markers are moved. | |
KMap | Too many inline functions in AbstractMarkerTiler::TileIndex? | |
KMap | No d-pointer in AbstractMarkerTiler? | |
KMap | Make sure all getter functions are const (getSelectionRectangle) |
TODO Later versions
Component | Job | Status |
---|---|---|
GPSSync | Support for loading KML files. |
DONE
Component | Job | Status |
---|---|---|
GPSSync | Remove the settings tab. | DONE |
Digikam | Also enable marker modes for the gpssearch? | DONE |
Digikam | Also enable marker modes for the center map. | DONE |
KMap | Switching from Marble to Google Maps does not keep rectangle selection mode | FIXED |
Digikam | Coordinates/altitude not shown in GPS properties tab sometimes. | FIXED |
Digikam | Mouse text "Remove the filtered image" indicates that images will be deleted, but we only remove the filtering. | FIXED |
KMap | KHTML shows some JavaScript errors in the digikam status bar when clicking around in the gps search. | FIXED |
Digikam | Modify GPS properties tab to only show altitude if there is one. | FIXED |
KMap | When no mouse mode buttons are shown, the control widget ends with a separator. | FIXED |
KMap | Put our definitions for the mouse modes into the wiki, because we will need them for the sprint when we talk about the UI with the others. | FIXED |
KMap | Do not hide the selection rectangle when the user switches to pan mode | FIXED |
All | Look through the code once more, there are still some places where digikam coding guidelines are not strictly followed, like "if(" or "for(" instead of "if (" and "for (", or spaces in empty lines. | FIXED |
Digikam | Save the map settings for the map view in the center. | FIXED |
KMap | Replace the B button with an "image" icon, for the E button use one of the markers as an icon. | FIXED |
Digikam/KMap | GPS properties tab: Make it possible to show markers instead of images, but find a way to disable moving of those markers for now. For this, the ModelHelper should not return the movable flag, and the flags should also be returned by the MarkerTiler, so that the kmap backends can check whether markers should be movable or not. Also, rename the enableEditMode function to enableMarkerMode or something, since the availability of "editing=moving" is managed by the model flags. | DONE |
GPSSync | Add license to rg-google-maps backend and/or move it out of the main directory. | FIXED |
- | Remove the gsoc-geocoding folder from SVN if it is no longer needed. | FIXED |
GPSSync | Configuration: Option to have two map views at the same time, with a horizontal or a vertical splitter. Useful when the user wants to look at Google Maps and OSM at the same time, or see the pictures closely and from far away at the same time. Plus, we need to use the model-view for something cool ;-) | DONE |
KMap | Use GeoCoordinate::Pair instead of QList<qreal> to emit the search rectangle coordinates | DONE |