Ok so I understand that when I upload a new image and it contains GPS data in the EXIF at some point it gets saved in the fields EXIFGPSLatitude, EXIFGPSLatitudeRef, EXIFGPSLongitude, EXIFGPSLongitudeRef
I would like to know when and how this happens.
What I would like to achieve (maybe it's even candidate for a feature request?) is that at this point when GPS data is found the location, city, state, country fields get automatically set in the database,. multilanguage.
I did some test with Google's reverse geocoding API and with looping over the generateLanguageList() function this data can be queried with a Curl.
Here is a function that I can call from image.php
`
function reverseGeoCode() {
$location = getImageData('location');
$city = getImageData('city');
$state = getImageData('state');
$country = getImageData('country');
// are the data fields [code]location, city, state, country[/code] empty in the database?
if (empty($location) && empty($city) && empty($state) && empty($country)) {
$lat = getImageData('EXIFGPSLatitude');
$lng = getImageData('EXIFGPSLongitude');
// is GPS data found in the EXIF?
if (!empty($lat) && !empty($lng)) {
(getImageData('EXIFGPSLatitudeRef') == "N") ? $lat_ref = "" : $lat_ref = "-";
(getImageData('EXIFGPSLongitudeRef') == "E") ? $lng_ref = "" : $lng_ref = "-";
$latlng = "$lat_ref$lat,$lng_ref$lng"; // string for Google
// multilanguage arrays for the fields
$arr_location = $arr_city = $arr_state = $arr_country = array();
// query Google Geocoding API to reverse geocode for each language
// http://code.google.com/apis/maps/documentation/geocoding/#ReverseGeocoding
$_languages = generateLanguageList();
foreach ($_languages as $text => $locale) {
$locale_code = substr($locale, 0, 2);
$geocodeURL = "http://maps.googleapis.com/maps/api/geocode/json?latlng=$latlng&language=$locale_code&sensor=false";
// Curl them (not tested on performance and delays yet)
$ch = curl_init($geocodeURL);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
// continue only if we get the correct response
if ($httpCode == 200) {
$geocode = json_decode($result);
// the data fields we are after
$g_location = $geocode->results[0]->address_components[0]->long_name;
$g_city = $geocode->results[0]->address_components[1]->long_name;
$g_province = $geocode->results[0]->address_components[2]->long_name;
$g_region = $geocode->results[0]->address_components[3]->long_name;
$g_country = $geocode->results[0]->address_components[4]->long_name;
$geo_status = $geocode->status;
// add the response data to the multilanguage arrays
$arr_location[$locale] = $g_location;
$arr_city[$locale] = $g_city;
$arr_state[$locale] = $g_province;
$arr_country[$locale] = $g_country;
}
/*
else {
$geo_status = "HTTP_FAIL_$httpCode";
$geo_str = "Failed: $geo_status";
}*/
}
// a static map image
// echo "";
// serialze the multilanguage arrays
echo "table [code]location[/code] : " . serialize($arr_location) . "
";
echo "table [code]city[/code] : " . serialize($arr_city) . "
";
echo "table [code]state[/code] : " . serialize($arr_state) . "
";
echo "table [code]country[/code] : " . serialize($arr_country) . "
";
}
}
}
`
So how and when can I set these fields? Or can I just do them from image.php?
What if I do a "refresh metadata" in the admin? Let's say I'll update the GPS data from an image. How can I update the other fields?
Any more points a need to be aware of? Will Curling like that work?
Cheers
My collegue is the meta data expert. But generally the reading and populating of the fields in the db happens on image discovery. It depends of course which metadata fields you enabled on the options.
You could probably do that on the theme side (image.php) but there should be filters for the backend (don't remember exactly right now, best you take a look at the plugin tutorial).
OK how to do it is fairly simple, I create an $imageobject and than
`
$imageobject->setLocation(serialize($arr_location));
$imageobject->setCity(serialize($arr_city));
$imageobject->setState(serialize($arr_state));
$imageobject->setCountry(serialize($arr_country));
$imageobject->save();
Works fine, the only thing is when and where. Right now I do it from image.php withreverseGeoCode()written in themes/mytheme/functions.php The advantage is that I don't have to mess around with core files. The only problem is that the image needs one first 'hit' before the data is written. And than there is the "update metadata" thing, it will not update the fields because of myif (empty($location) && empty($city) && empty($state) && empty($country))` statement
Any suggestions or thoughts very welcome!
Hi, okay I have a first version, please let me know what you guys think...
Performance wise all seems to work with the cURL's, although a "refresh metadata" on a database with a LOT of images will make a lot of calls to Google. Each image multiplied by the number of active languages. Google lets you do query limit of 2,500 geolocation requests per day: http://code.google.com/apis/maps/documentation/geocoding/#Limits
I also need to test what happens on an installation with the multi language not active btw.
I have not tested it against the xmpMetadata plugin. I think you can set some sort of priority right? Is this necessary or will one just override the fields in the database?
What I would also like to integrate is some sort of lock if the location, city, state & country fields are already filled out. For example I reverse_geocode the image(s) and than correct the location field with admin-edit.php. The next time I do a "refresh metadata" the fields will be overriden.. I would like some option to lock a particular field from a particular image. I think it's especially useful for the location field.
For example, instead of the geocoded street name I could want something like "old town".
Any ideas very welcome.
Anyway, here is the plugin attempt:
`
Quote:I also need to test what happens on an installation with the multi language not active btw.
If you correctly handle multi-lingual fields there should be no issue with sites that are not multi-lingual. At least not from the Zenphoto standpoint. (BTW: I did not review your code. Too much trouble here. Maybe you can create a ticket and attach it there. That would be much more convenient to browse.)
Quote:I have not tested it against the xmpMetadata plugin. I think you can set some sort of priority right? Is this necessary or will one just override the fields in the database?
Filters can be prioritized. As things stand, they will apply their changes in the order they run, so the "last" one wins. The filters all happen after the normal within the image metadata is stored. If there are multiple plugins handling metadata it is an interesting question as to which one should take precidence. As well at present there is no way for the site manager to change the priorities short of hacking the code. Maybe something we should consider.
Quote:What I would also like to integrate is some sort of lock if the location, city, state & country fields are already filled out. For example I reverse_geocode the image(s) and than correct the location field with admin-edit.php. The next time I do a "refresh metadata" the fields will be overriden.. I would like some option to lock a particular field from a particular image. I think it's especially useful for the location field.
For example, instead of the geocoded street name I could want something like "old town".
Your plugin can test to see if the field is "empty" and only store if it is. Of course if you do this, then even if the data changes your plugin will not update it. (Not sure how the geo location could change, but I suppose there could be changes in the political boundries.) Refresh Metadata is really intended to do just what you wish to avoid.
Ok I could use file_get_contents if cURL is not enabled.
Good point about only populating the field when it is empty. That makes sense because this data can be edited from the admin anyway. So I will slipstream the "empty" statement.
I will update the plugin and do more tests in a few days as I am occupied this week.
Laters.
OK, I think I got it now.
I took into account all your considerations and added a "rescan" option that will give control on preserving edits.
By default the "rescan all" option is unchecked and only images that are not geocoded (no data in the fields) will process. You can actually rescan specific images and individual fields when you clear a field in admin-edit and to a "metadata refresh"
When the option is checked all images and fields can be re-geocoded again, overriding the old values. This option could also be refined by specifying which fields should be scanned for all images.
I think these options give you a lot of control. (at least if understood, I hope I did the descriptions okay)
I tested both single and multi language installs and implemented the $plugin_disable if curl_init does not exist.
The plugin will not work when IPTC sublocation, IPTC city, IPTC state/province or IPTC country data is present in the image (for example you could do this in Lightroom)
ZP is too dominant in this case :-P
`
I have put it up on: http://code.google.com/p/zenphoto-google-reverse-geocode/
What do you mean unreadable?
I used the backticks around the code. A lot of tabs, you just need to scroll?
Anyway yes it is tested and working. At least on my localhost installation it is...
One thing I need to do is the translations. I just read about the gettext_pl() this morning...
I will update it soon to v0.3
Not sure what you mean about an entry in the extensions section but I will check it out.
Doing this plugin was a great experience btw. The more time I spend with ZP the more I realize how awesome ZP is! If I would have only known a earlier :-)
Big thumbs up to the ZP team for all knowlage and work you guys have put into this, but most of all the support on this forum.
Soon when things calm down at work I will put my site online. And as soon as it is make a donation!
Cheers!
Well, not unreadable in the true sense, it just does not make any fun to look at such long code on the forum..;-)
Quote:Not sure what you mean about an entry in the extensions section but I will check it out.
www.zenphoto.org/news/category/extensions
There you find entries of all official and also all third party extensions (at least all we know of).
You cannot add it yourself so we do and link to your page where you host your plugin. That way other find it easier in case they need it. (see the "Get involved" link on top or directly the "Contributor guidelines"). In this case tha would be probably the google code page (but later maybe your own site as you surely would benefit from our sites rank and traffic).