Skip to content

Instantly share code, notes, and snippets.

@philippschmitt
Last active May 13, 2020 22:02
Show Gist options
  • Save philippschmitt/5a676537bf7712164395 to your computer and use it in GitHub Desktop.
Save philippschmitt/5a676537bf7712164395 to your computer and use it in GitHub Desktop.
Count all photos that are available on Flickr and Panoramio for a specific geo fence
/*
This script counts all photos that are available on Flickr and Panoramio for a specific geo fence and returns a JSON object with the data.
For convenience it's embedded in a little node.js server so that you can upload it to your server and use it as an API.
Here's an example url with all query attributes prefilled. Please use your own Flickr API key!
The location is the Berlin TV Tower (http://en.wikipedia.org/wiki/Fernsehturm_Berlin)
Example URL: http://piccounter-philippschmitt.rhcloud.com/?lat=52.520732&lon=13.409537&latRes=0.00015&lonRes=0.0003&flickrKey=60d03369d3e92b4578c8f2df2de5af66
Created 2014-10-26
by Philipp Schmitt
http://philippschmitt.com
*/
// load modules
var http = require('http'),
qs = require('qs'),
url = require('url'),
request = require('request');
// create the http server
http.createServer(function (req, res) {
// parse URL and create object containing GET vars
var url_parts = url.parse(req.url, true);
var query = url_parts.query;
// check if query string is ok
if( query.lat && query.latRes && query.lon && query.lonRes && query.flickrKey ) {
// load photos
countPhotosForCurrentPosition( parseFloat(query.lat), parseFloat(query.latRes), parseFloat(query.lon), parseFloat(query.lonRes), query.flickrKey, function( result ) {
// callback:
// serve query results as JSON
res.writeHead(200, {'Content-Type': 'application/json'});
res.end( JSON.stringify(result) );
});
// nope. bad request
} else {
res.writeHead(400, {'Content-Type': 'application/json'});
res.end( JSON.stringify({}) );
}
// listen to port: 8124
}).listen(8124);
// function to load photos asynchronously
var countPhotosForCurrentPosition = function(lat, latRes, lon, lonRes, flickrKey, callback) {
// define helper vars
var total = 0,
flickr = 0,
pnrmio = 0,
flickrDone = false,
pnrmioDone = false;
// FLickr Query URL
var flickrURL = 'https://api.flickr.com/services/rest/?api_key='+ flickrKey +'&method=flickr.photos.search&bbox='+ (lon-lonRes) +'%2C'+ (lat-latRes) +'%2C+'+ (lon+lonRes) +'%2C+'+ (lat+latRes) +'&min_upload_date=820483200&accuracy=16&format=json&nojsoncallback=1&content_type=1&has_geo=1';
// Panoramio Query URL array
var pnrmioURL = [];
// FLICKR Query
request(flickrURL, function (error, response, body) {
if (!error && response.statusCode == 200) {
var data = JSON.parse(body);
// Add all photos to our counter
flickr += parseInt( data.photos.total );
// confirm that flickr is done counting photos
flickrDone = true;
} else {
// an error occured
console.log('Flickr error');
}
});
// PANORAMIO Query
/* Helper function:
* The Panoramio photos.count attribute is inaccurate.
* We have to go through all available photos and count.
* But Panoramio queries are limited to 100 photos.
* That's why we query over and over again
*/
var queryPanoramio = function (from, to) {
var options = {
url: 'http://www.panoramio.com/map/get_panoramas.php?set=full&from='+ from +'&to='+ to +'&minx='+ (lon-lonRes) +'&miny='+ (lat-latRes) +'&maxx='+ (lon+lonRes) +'&maxy='+ (lat+latRes) +'&size=small&mapfilter=false',
json: true,
method: 'GET'
};
// add current query URL to list
pnrmioURL.push( options.url );
// do the actual request
request(options, function (error, response, body) {
// success: work with the data
if (!error && response.statusCode == 200) {
// add length of photo array (i.e. number of photos) to our counter
pnrmio += body.photos.length;
// Are there more photos?
if( to+99 <= body.count && body.has_more==true ) {
// yep: query the next 100 pics
queryPanoramio(to+1, to+100);
} else {
// we're done.
pnrmioDone = true;
}
} else {
// an error occured
console.log('Panoramio error');
}
});
};
// do the initial query
queryPanoramio(0,100);
// check every 10ms, if both Flickr and Panoramio are done counting
var waiter = setInterval(function() {
// it's time!
if( flickrDone == true && pnrmioDone==true ) {
// stop waiter
clearInterval(waiter);
// invoke callback function and return results object
callback({
// total amount of photos
total: flickr + pnrmio,
// flickr subsection
flickr: {
// all photos fetched from flickr
total: flickr,
// the Flickr query URL
flickrURL: flickrURL
},
// Panoramio subsection
pnrmio: {
// number of photos fetched from Panoramio
total: pnrmio,
// query URLs for Panoramio API
pnrmioURL: pnrmioURL
}
});
}
}, 10);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment