NAME
Net::Flickr::Geo::ModestMaps - tools for working with geotagged Flickr photos and Modest Maps
SYNOPSIS
my %opts = ();
getopts('c:s:', \%opts);
#
# Defaults
#
my $cfg = Config::Simple->new($opts{'c'});
#
# Atkinson dithering is hawt but takes a really long
# time...
#
$cfg->param("modestmaps.filter", "atkinson");
$cfg->param("modestmaps.timeout", (45 * 60));
#
# Let's say all but one of your photos are in the center of
# Paris and the last one is at the airport. If you try to render
# a 'poster style' (that is all the tiles for the bounding box
# containing those points at street level) map you will make
# your computer cry...
#
$cfg->param("pinwin.skip_photos", [506934069]);
#
# I CAN HAS MAPZ?
#
my $fl = Net::Flickr::Geo::ModestMaps->new($cfg);
$fl->log()->add(Log::Dispatch::Screen->new('name' => 'scr', min_level => 'info'));
my $map_data = $fl->mk_poster_map_for_photoset($opts{'s'});
#
# returns stuff like :
#
# {
# 'url' => 'http://127.0.0.1:9999/?provider=YAHOO_AERIAL&marker=yadda yadda yadda',
# 'image-height' => '8528',
# 'marker-484080715' => '5076,5606,4919,5072,500,375',
# 'marker-506435771' => '5256,4768,5099,542,500,375',
# 'path' => '/tmp/dkl0o7uxjY.jpg',
# 'image-width' => '6656',
# }
#
my $results = $fl->upload_poster_map($map_data->{'path'});
#
# returns stuff like :
#
# [
# ['/tmp/GGsf4552h.jpg', '99999992'],
# ['/tmp/kosfGgsfdh.jpg', '99999254'],
# ['/tmp/h354jF590.jpg', '999984643'],
# [ and so on... ]
# ];
#
DESCRIPTION
Tools for working with geotagged Flickr photos and the Modest Maps ws-pinwin HTTP service.
OPTIONS
Options are passed to Net::Flickr::Backup using a Config::Simple object or a valid Config::Simple config file. Options are grouped by "block".
flickr
api_key
String. required
A valid Flickr API key.
api_secret
String. required
A valid Flickr Auth API secret key.
auth_token
String. required
A valid Flickr Auth API token.
The api_handler defines which XML/XPath handler to use to process API responses.
LibXML
Use XML::LibXML.
XPath
Use XML::XPath.
pinwin
map_height
The height of the background map on which the pinwin/thumbnail will be placed.
Default is 1024.
map_width
The width of the background map on which the pinwin/thumbnail will be placed.
Default is 1024.
upload
Boolean.
Automatically upload newly create map images to Flickr. Photos will be tagged with the following machine tags :
flickr:photo=photo_id
Where photo_id is the photo that has been added to the map image.
flickr:map=pinwin
Default is false.
upload_public
Boolean.
Mark pinwin uploads to Flickr as viewable by anyone.
Default is false.
upload_friend
Boolean.
Mark pinwin uploads to Flickr as viewable only by friends.
Default is false.
upload_family
Boolean.
Mark pinwin uploads to Flickr as viewable only by family.
Default is false.
photo_size
String.
The string label for the photo size to display, as defined by the flickr.photos.getSizes API method :
http://www.flickr.com/services/api/flickr.photos.getSizes.html
Default is Medium
zoom
Int.
By default, the object will try to map the (Flickr) accuracy to the corresponding zoom level of the Modest Maps provider you have chosen. If this option is defined then it will be used as the zoom level regardless of what Flickr says.
crop_width
Int.
Used by the crop_poster_map (and by extension upload_poster_map) object methods to define the width of each slice taken from a poster map.
Default is 1771
crop_height
Int.
Used by the crop_poster_map (and by extension upload_poster_map) object methods to define the height of each slice taken from a poster map.
Default is 1239
skip_photos
Int (or array reference of ints)
Used by photoset related object methods, a list of photos to exclude from the list returned by the Flickr API.
skip_tags
String (or array reference of strings)
Used by photoset related object methods, a list of tags that all photos must not have if they are to be included in the final output.
ensure_tags
String (or array reference of strings)
Used by photoset related object methods, a list of tags that all photos must have if they are to be included in the final output.
modestmaps
server
The URL to a server running the ws-pinwin.py HTTP interface to the ModestMaps tile-creation service.
This requires Modest Maps 1.0 release or higher.
provider
A map provider and tile format for generating map images.
As of this writing, current providers are :
MICROSOFT_ROAD
MICROSOFT_AERIAL
MICROSOFT_HYBRID
GOOGLE_ROAD
GOOGLE_AERIAL
GOOGLE_HYBRID
YAHOO_ROAD
YAHOO_AERIAL
YAHOO_HYBRID
method
Used only when creating poster maps, the method parameter defines how the underlying map is generated. Valid options are :
extent
Render map tiles at a suitable zoom level in order to fit the bounding box (for all the images in a photoset) in an image with specific dimensions (pinwin.map_height and pinwin.map_width).
bbox
Render all the map tiles necessary to display the bounding box (for all the images in a photoset) at a specific zoom level.
Default is bbox.
bleed
If true then extra white space will be added the underlying image in order to fit any markers that may extend beyond the original dimensions of the map.
Boolean.
Default is true.
adjust
Used only when creating poster maps, the adjust parameter tells the modest maps server to extend bbox passed by n kilometers. This is mostly for esthetics so that there is a little extra map love near pinwin located at the borders of a map.
Boolean.
Default is .25
filter
Tell the Modest Maps server to filter the rendered map image before applying an markers. Valid options are :
atkinson
Apply the Atkinson dithering filter to the map image.
This is brutally slow. Especially for poster maps. That's life.
timeout
Int.
The number of seconds the object's HTTP handler will wait when requesting data from the Modest Maps server.
Default is 300 seconds.
PACKAGE METHODS
__PACKAGE__->new($cfg)
Returns a Net::Flickr::Geo object.
PINWIN MAPS
$obj->mk_pinwin_map_for_photo($photo_id)
Fetch a map using the Modest Maps ws-pinwin API for a geotagged Flickr photo and place a "pinwin" style thumbnail of the photo over the map's marker.
Returns an array of arrays (kind of pointless really, but at least consistent).
The first element of the (second-level) array will be the path to the newly created map image. If uploads are enabled the newly created Flickr photo ID will be passed as the second element.
$obj->mk_pinwin_maps_for_photoset($photoset_id)
For each geotagged photo in a set, fetch a map using the Modest Maps ws-pinwin API for a geotagged Flickr photo and place a "pinwin" style thumbnail of the photo over the map's marker.
If uploads are enabled then each map for a given photo will be added such that it appears before the photo it references.
Returns an array of arrays.
The first element of each (second-level) array reference will be the path to the newly created map image. If uploads are enabled the newly created Flickr photo ID will be passed as the second element.
POSTER MAPS
$obj->mk_poster_map_for_photoset($set_id)
For each geotagged photo in a set, plot the latitude and longitude and create a bounding box for the collection. Then fetch a map for that box using the Modest Maps ws-pinwin API for a geotagged Flickr photo and place a "pinwin" style thumbnail for each photo in the set.
Automatic uploads are not available for this method since the resultant images will almost always be too big.
Returns a hash reference containing the URL that was used to request the map image, the path to the data that was sent back as well as all of the Modest Maps specific headers sent back.
$obj->upload_poster_map($poster_map)
Take a file created by the mk_poster_map_for_photoset and chop it up in "postcard-sized" pieces and upload each to Flickr.
Returns an array of arrays.
The first element of the (second-level) array will be the path to the newly created map image. If uploads are enabled the newly created Flickr photo ID will be passed as the second element.
$obj->crop_poster_map($poster_map)
Take a file created by the mk_poster_map_for_photoset and chop it up in "postcard-sized" pieces.
The height and width of each piece are defined by the pinwin.crop_width and pinwin.crop_height config options.
Any image whose cropping creates a file smaller than either dimension will be padded with extra (white) space.
Returns a list of files.
CLUSTER MAPS
$obj->mk_cluster_maps_for_photo($photo_id)
Like poster maps, cluster maps plot many photos in multiple pinwins on a single background map image. Unlike poster maps, where you explicitly list all the photos to display (by specifying a photo set) cluster maps renders a single photo as its principal focus with all the photos with in an (n) kilometer radius of the subject photo.
Multiple photos sharing the same latitude and longitude are also clustered together and rendered in a single pinwin, whose size and shape is relative to the square root of the number of total photos. This helps, in densely photographed areas, to prevent cascading pinwins from rocketing off the map canvas trying to find a suitably empty space to avoid overlapping other nearby pinwins.
As of this writing, all the surrounding photos are rendered using their 75x75 pixel square thumbnail though this will be a user-configurable option in future releases. The principal photo size can still be set by assigning the pinwin.photo_size config variable (the default is Medium).
Cluster maps are not a general purpose interface to the Flickr photos.search method (yet) although there are some flags to limit search results to the principal photo's owner or by one or more copyright licenses.
All (except method, discussed below) the usual config options may be set for cluster maps. In addition, you may also define the following options :
clustermap.radius
Float.
The number of kilometers from $photo_id's lat/lon in which to perform a radial query for other geotagged photos.
Default is 1
clustermap.offset
Int.
The number of days on either side of $photo_id's "date taken" value with which to limit the scope of the query.
Default is 0
clustermap.only_photo_owner
Boolean.
Limit all queries to include only photos uploaded by $photo_id's owner.
Default is true
clustermap.force_photo_owner
Boolean.
Typically used when setting the photo_license to ensure that nearby photos uploaded by $photo_ids owner are included. If true, this will cause the code to execute the same search twice. The second query will remove any licensing restrictions and enforce that only photos owned by $photo_id's owner be returned. The two result sets will then be merged and sorted by distance from the center point.
(Ignored if the clustermap.only_photo_owner is true.)
Default is false
photo_license
String.
A comma-separated list of Flickr license IDs to limit the list of photos returned by the photos.search API method.
Default is none.
clustermap.geo_perms
String.
Post search, ensure that all the photos have a minimum set of geo permissions.
Valid options are : "public", "contact", "friend", "family", "friend or family" and "all".
Default is all
clustermap.max_photos
Int.
Although the clustering of photos sharing the same latitude and longitude helps cut down on number of pinwins the Modest Maps needs to figure out how to layout on the background map, there is still an upper limit after which it (Modest Maps) will simply give up.
The exact number is a little hard to say as it is usually a function of how closely grouped any number of pinwins (clustered or not) are to each other. Anecdotally, anything less than 100 is fine; less than 200 is a toss up; anything after that usually wakes the baby.
Default is 100
clustermap.max_photos_per_group
Int.
All of the clusters are grouped by their lat/lon position rounded off to three decimal points. You can change this option to set the maximum number of photos that can be contained in a single group.
Default is half the value of the clustermap.max_photos parameter.
If either the max_photos or max_photos_per_group is exceeded then another search query is initiated, where the radial days offset from $photo_id's taken date is reduced by 10%. If no offset value was set by the user then an initial value of 365 is set (meaning that if there are still too many photos after the second query it will be reset to 328 days and so on.)
Finally, all cluster maps assume the Modest Maps bbox method. The bounding box itself is calcluated using the photos further from the center and is adjusted (in size) relative to distance between the south-west and north-east corners.
If the distance is less that 1km, the bounding box will be expanded by .25km; If the distance is less than 1.5km, the bounding box will be expanded by .1km; If the bounding is less than 2km, the bounding box will be expanded by .1km.
Returns a hash reference containing the URL that was used to request the map image, the path to the data that was sent back as well as all of the Modest Maps specific headers sent back.
Attribution for the photos is returned in a hash refernce whose key is labeled attribution and whose contents are a series of nested hashes mapping marker IDs to owners and a list of photos for that marker. For example :
$response = {
# lots of other stuff
'marker-2561168539' => '1455,4189,1427,2065,75,75',
'attribution' => {
'2366199422' => {
'foobar' => ['http://www.flickr.com/photos/foobar/999999'],
}
}
}
$obj->mk_historical_cluster_map_for_photo($photo_id)
Historical cluster maps are similar to plain old cluster in nature, but not in execution. Rather than doing a single query and showing whatever happens to be closest to $photo_id historical cluster maps rely on the code making two calls to the photos.search each explicitly constrained by a date range.
The first query will ask for photos within (n) days of when the photo was taken; the second query will ask for photos within (n) days of today.
The two result sets are then smushed together, sorted by distance to $photo_id and clustered in to groups. If the number of photos, or grouped photos, is too high then each date range is reduced (the value of offset days is multiplied by 90% and rounded down) and the process is repeated until everything fits.
Or something breaks.
Then we make a map!
All the same rules and options that apply for plain old cluster maps are valid for historical cluster maps.
VERSION
0.711
DATE
$Date: 2008/07/05 16:56:23 $
AUTHOR
Aaron Straup Cope <ascope@cpan.org>
EXAMPLES
http://flickr.com/photos/straup/tags/modestmaps/
REQUIREMENTS
Modest Maps 1.0 or higher.
NOTES
All uploads to Flickr are marked with a content-type of "other".
SEE ALSO
http://mike.teczno.com/notes/oakland-crime-maps/IX.html
http://www.aaronland.info/weblog/2008/02/05/fox/#ws-modestmaps
BUGS
Sure, why not.
Please report all bugs via http://rt.cpan.org
LICENSE
Copyright (c) 2007-2008 Aaron Straup Cope. All Rights Reserved.
This is free software. You may redistribute it and/or modify it under the same terms as Perl itself.
2 POD Errors
The following errors were encountered while parsing the POD:
- Around line 129:
'=item' outside of any '=over'
- Around line 243:
You forgot a '=back' before '=head2'