Flickr-Upload-FireEagle

 view release on metacpan or  search on metacpan

lib/Flickr/Upload/FireEagle.pm  view on Meta::CPAN

is updated with the latitude and longitude recorded in the photo.

Moving right along, whether or not we've just updated FireEagle the service is queried
for your current location (again).

Once the hierarchy has been retrieved, the next step is to try and retrieve a "context" node.
Whereas when testing GPS information the "best guess" node is assumed this is not necessarily
the case when trying to use FireEagle to add tags.

The context node is determined by comparing the photo's date against the I<located-at> (or
date recorded) attribute for specific items in the FireEagle hierarchy. Since most cameras
still don't record GPS information it is necessary to do some work to gues^H^H^H I mean 
infer how "close" you are to the last recorded location.

For example, if it's been more than a couple of hours since you last updated FireEagle you
might still be in the same neighbourhood but if it's been more than half a day chances are
good that you're been on the move but are still in the same city.

(It goes without saying that there are lots of edge cases some of which will try to be addressed
in the as-yet unwritten Flickr::Upload::FireDopplr.)

The following tests are applied : 

=over 4

=item * First a "best guess" location is queried

If it is present and its I<located-at> date is less than or equal to an hour, it is the
context node.

An alternate value may be set by passing a I<offset_fireeagle_exact> argument, measured in
seconds, to the I<upload> method.

=item * Next a location of type "neighborhood" is queried

If it is present and its I<located-at> date is less than or equal to two hours, it is the
context node.

An alternate value may be set by passing a I<offset_fireeagle_neighbourhood> (or neighborhood) 
argument, measured in seconds, to the I<upload> method.

=item * Next a location of type "locality" is queried

If it is present and its I<located-at> date is less than or equal to twelve hours, it is the
context node.

An alternate value may be set by passing a I<offset_fireeagle_locality> argument, measured
in seconds, to the I<upload> method.

=item * If none of those tests pass then...

...there is no context node.

=back

Assuming that a context node has been identified I<and> there is GPS information stored in the
photo, the I<flickr.places.findByLatLon> method is called (passing the photo's latitude and
longitude) to ensure that the (Flickr) places IDs for both the response and the context node match.

If they I<don't> match then the context node is destroyed and the following tags are added :
places:PLACETYPE=PLACEID; woe:id=WOEID; the name of the location (formatted according to the
object's "tagify" rules). 

On the other hand, if the context node is still around, after all that, then it is used to add tags.

At a minimum a fireeagle:id=CONTEXTNODEID tag is added. If the place type for the context node is
equal to or more precise than a neighbourhood, the neighbourhood's name is added as a tag. If the
place type for the context node is equal to or more precise than a locality, the locality's name
is added as a tag as well as fireeagle:id=ID, places:locality=PLACEID and woe:id=WOEID tags.

We're almost done : Assuming a context node and no GPS information in the photo, the nodes latitude
and longitude are calculated to use as arguments when calling the I<flickr.photos.geo.setLocation>
method.

The coordinates are "calculated" because not every location in the FireEagle hierarchy has a centroid.
If no centroid is present then the node's bounding box is used and the centroid is assumed to be
the center of the box. The photo's "accuracy" (in Flickr terms) is determined according to the node's
place type.

Finally, the photo is uploaded (and geotagged if necessary).

No really.

=head1 ERROR HANDLING

Flickr::Upload::FireEagle subclasses Error.pm to catch and throw exceptions. Although
this is still a mostly un-Perl-ish way of doing things, it seemed like the most sensible
way to handle the variety of error cases. I don't love it but we'll see.

This means that the library B<will throw fatal exceptions> and you will need to
code around it using either I<eval> or - even better - I<try> and I<catch> blocks.

There are four package specific exception handlers :

=over 4

=item * B<FUFEException>

An error condition specific to I<Flickr::Upload::FireEagle> was triggered.

=item * B<FlickrUploadException>

An error condition specific to I<Flickr::Upload> was triggered.

=item * B<FlickrAPIException>

An error condition specific to calling the Flickr API (read : I<Flickr::API>)
was triggered.

This is the only exception handler that defines its own additional methods. They
are :

=over 4

=item * B<error_code>

The numeric error code returned by the Flickr API.

=item * B<error_message>

The textual error message returned by the Flickr API.



( run in 0.969 second using v1.01-cache-2.11-cpan-9581c071862 )