Sunday, September 22, 2013

Aperture AppleScript to write Location data into IPTC fields.

Hereby a post about an AppleScript I wrote for Aperture: Get GeoNames and Keywords.  

One of the items I missed when I started to use Aperture was a way to have the Places/Location data stored in the (original) picture's respective IPTC fields.  I like it to be stored in the original file because I work referenced and I like to have that data available to other applications outside of Aperture when needed. 

The scipt uses the Long. and Lat. coordinates of a media file and will retrieve from Google by the use of the Location Helper tool by David Blishen, the geo names of the location and accordingly adds these to the IPTC fields of the media file. It adds them as keywords also.  When the scrip has completed you can use the Aperture function METADATA > Write IPTC data to Original to write the values to the original media file.

I'm not a programmer by profession and am pretty new on the Mac, Aperture as well as AppleScript, so suggestions and constructive feedback are always welcome.

Although I use the script myself, the use of this script is at your own risk and is provided as-is without guarantee or warranty. Before you use it, it is strongly advised to ensure you have a backup of your media files and your library and you run the script first on a Aperture test library.

Further instructions on how the script works is part of the script below. I hope it may help some of you too.

Regards,
Luc


The Get GeoNames and Keywords.SCPT: (Copy/Paste the below lines) 


(*

GEO NAMESS AND KEYWORDS.SCPT  Version 1 BETA
©2013, L. Le Lievre
Get GeoNames and Keywords is a script which uses  the long. and Lat. coordinates of a media file and will retrieve from Google by the use of the Location Helper tool By David Blishen, the geo names of the location and accordingly adds these to the IPTC fields of the media file. In addition it will add these as keywords also.  When the script has completed you can use the Aperture function METADATA > Write IPTC data to Original to write the values to the original media file so it is available outside aperture.
When the GEO location has been retrieved the following IPTC fields will get populated:
Country/PrimaryLocationCode with the Short name of the Country Code
Country/PrimaryLocationName with the Long name of the Country Code
City with the Long Locality Name
SubLocation with the Long SubLocality 
Province/State with the Long name of Administrative Area Level 2
In addition the Location will be added as Keywords as follow:
The Parent keyword willl be the Long Country code
Then the following keywords will be added as hirarchical keywords below the parent (Long Country Code)
Long Country CodeLong Locality Name
Long Establishment Name

In case the Script has run Succesful, all Color labels will be removed (ATTENTION IF YOU ALREADY USE COLOR LABEL CODING !!)
In case no Long/LAt Coordinates are available in the selected media file, the media file will be assigned a RED color Label
In case the media file does have coordinates but the retrieval of the reverse geocode location was not successful, the media File will be marked ORANGE. 
The use of this script is at your own risk and is provided as-is without gurarantee or warrantee.
Before use it is strongly advised to ensure you have a backup of your media and you run the script first on a Aperture test library.
The scrip requires the tool LOCATION HELPER By David Blishen
More information regarding the tool cna be found at http://www.mousedown.net/mouseware/LocationHelper.html.  The tool can be downloaded from the App Store.
For Usage Rights and limitations on the Google GEO Coding, please see Google usage Rights at 
Information, suggestions or constructive feedback to correct or enhance the script can be sent to AppleScript@le-lievre.com
*)

set importProjects to {}

tell application "Aperture"
activate
set imageSelection to (get selection)
if imageSelection is {} then
display dialog "Please select an image in Aperture" with title "GeoNames Lookup" buttons {"Okay"}
return
else
global ap_ImageFileName
global ap_ImageLat
global ap_ImageLng
global ap_ColorLabel
global gl_Status
global gl_Ok
global gl_NotFound
global gl_QueryLimitReached
global gl_RequestDenied
global gl_InvalidRequest
global gl_UnknownError
global ap_kwLocation
global ap_kwLocation
set gl_Ok to "OK"
set gl_NotFound to "ZERO_RESULTS"
set gl_QueryLimitReached to "OVER_QUERY_LIMIT"
set gl_RequestDenied to "REQUEST_DENIED"
set gl_InvalidRequest to "INVALID_REQUEST"
set gl_UnknownError to "UNKNOWN_ERROR"
set ap_kwLocation to "Location"
set ap_kwCountry to "Country"
repeat with currentImage in imageSelection
try
tell currentImage
set ap_ImageFileName to ""
set ap_ImageLat to ""
set ap_ImageLng to ""
try
set ap_ImageFileName to value of other tag "FileName"
set ap_ImageLat to value of EXIF tag "Latitude"
set ap_ImageLng to value of EXIF tag "Longitude"
set ap_ColorLabel to color label
log ap_ColorLabel
tell application "Location Helper"
set geoJSON to ""
set gl_street_address_short to ""
set gl_route_short to ""
set gl_political_short to ""
set gl_country_short to ""
set gl_administrative_area_level_1_short to ""
set gl_administrative_area_level_2_short to ""
set gl_administrative_area_level_3_short to ""
set gl_colloquial_area_short to ""
set gl_locality_short to ""
set gl_sublocality_short to ""
set gl_neighborhood_short to ""
set gl_premise_short to ""
set gl_subpremise_short to ""
set gl_postal_code_short to ""
set gl_natural_feature_short to ""
set gl_airport_short to ""
set gl_park_short to ""
set gl_point_of_interest_short to ""
set gl_establishment_short to ""
set gl_street_address_long to ""
set gl_route_long to ""
set gl_political_long to ""
set gl_country_long to ""
set gl_administrative_area_level_1_long to ""
set gl_administrative_area_level_2_long to ""
set gl_administrative_area_level_3_long to ""
set gl_colloquial_area_long to ""
set gl_locality_long to ""
set gl_sublocality_long to ""
set gl_neighborhood_long to ""
set gl_premise_long to ""
set gl_subpremise_long to ""
set gl_postal_code_long to ""
set gl_natural_feature_long to ""
set gl_airport_long to ""
set gl_park_long to ""
set gl_point_of_interest to ""
set gl_establishment_long to ""
try
set gl_Data to reverse geocode location using coordinates {ap_ImageLatap_ImageLng}
set gl_Status to status of gl_Data
if gl_Status is gl_Ok then
set gl_record to address_components of item 1 of results of gl_Data
repeat with g from 1 to (count of gl_record)
set gl_itemlist to item g of gl_record as list
set gl_type to item 3 of gl_itemlist
if gl_type contains "route" then
set gl_route_short to item 1 of gl_itemlist
set gl_toute_long to item 2 of gl_itemlist
else
if gl_type contains "locality" then
set gl_locality_short to item 1 of gl_itemlist
set gl_locality_long to item 2 of gl_itemlist
else
if gl_type contains "country" then
set gl_country_short to item 1 ofgl_itemlist
set gl_country_long to item 2 ofgl_itemlist
else
if gl_type contains "sublocality" then
set gl_sublocality_short toitem 1 of gl_itemlist
set gl_sublocality_long toitem 2 of gl_itemlist
else
if gl_type contains"establishment" then
setgl_establishment_short to item 1 of gl_itemlist
setgl_establishment_long to item 2 of gl_itemlist
else
if gl_typecontains "administrative_area_level_2" then
setgl_administrative_area_level_2_short to item 1 of gl_itemlist
setgl_administrative_area_level_2_long to item 2 of gl_itemlist
end if
end if
end if
end if
end if
end if
end repeat
--DEBUG LINES TO VALIDATE CONTENT OF RETRIEVED FIELDS DURING DEBUG
--log "----------------"
--log "Result:"
--log gl_route_short
--log gl_locality_short
--log gl_country_short
--log gl_country_long
--log gl_sublocality_short
--log gl_sublocality_long
--log gl_administrative_area_level_2_short
--log gl_administrative_area_level_2_long
--log gl_establishment_short
--log gl_establishment_long
--log "----------------"
end if
on error errTxt number errNo
set gl_Status to status of gl_Data
end try
end tell
log gl_Ok
log gl_Status
if gl_Status is not gl_Ok then
set color label to orange
-- NOTE: If the retrieve of the Location data failed, the color label of the image is changed to orange. Initially thre was also an error discplayed, but if you have the error on many of the images, because e.g. you have overrun the max number to be located per day by Google, there were too many errors to confirm.  Therefor line has been removed
-- if gl_Status is gl_QueryLimitReached then display dialog "Error,  daily query limit reached for Google Maps API on file:  " & ap_ImageFileName buttons {"Ignore", "Cancel"} cancel button "Cancel" giving up after 10 with title "Geo Addressing Error" with icon note
else
-- SET KEYWORDS IN APERTURE TO RETRIEVED LOCATION
if gl_sublocality_long is "" then
set gl_sublocality_short to gl_establishment_short
set gl_sublocality_long to gl_establishment_long
end if
make new IPTC tag with properties {name:"Country/PrimaryLocationCode", value:gl_country_short}
make new IPTC tag with properties {name:"Country/PrimaryLocationName", value:gl_country_long}
make new IPTC tag with properties {name:"City", value:gl_locality_long}
make new IPTC tag with properties {name:"SubLocation", value:gl_sublocality_long}
make new IPTC tag with properties {name:"Province/State", value:gl_administrative_area_level_2_long}
set kwParents to gl_country_long & tab & ap_kwLocation
make new keyword with properties {name:gl_country_longparents:{ap_kwCountry}}
make new keyword with properties {name:gl_locality_longparents:{kwParents}}
make new keyword with properties {name:gl_establishment_longparents:{kwParents}}
-- WHEN SUCCSESFUL REMOVE THE COLOR CODING OF THE IMAGE
set color label to no color label
end if
on error errTxt number errNo
-- IN CASE NO LONG/LAT COORDINATES ARE AVAILABLE IN THE MEDIA FILE IN APERTURE? SET THE COLOR LABEL OF THE MEDIA TO RED.
if errNo = -1728 then
set color label to red -- no geo coordinates found then set color label to red
else
display dialog "Error: " & errNo & ": " & errTxt
end if
end try
end tell
on error errTxt number errNo
if errNo = -1728 then
-- no geo coordinates display dialog "Error, no EXIF GPS data available in image: " & ap_ImageFileName buttons {"Ignore", "Cancel"} cancel button "Cancel" giving up after 10 with title "Geo Addressing Error" with icon note
else
display dialog "Error: " & errNo & ": " & errTxt
end if
end try
end repeat
end if
-- end tell -- Library
end tell -- Aperture