Warning: ini_get_all() has been disabled for security reasons in /home/eatyourg/public_html/wp-includes/load.php on line 1160

Warning: ini_get_all() has been disabled for security reasons in /home/eatyourg/public_html/wp-includes/load.php on line 1160

Warning: Cannot modify header information - headers already sent by (output started at /home/eatyourg/public_html/wp-includes/load.php:1160) in /home/eatyourg/public_html/wp-includes/feed-rss2.php on line 8
astronomy – Eat your greens! http://eatyourgreens.org.uk Actually, I am a rocket scientist Wed, 10 Oct 2012 14:24:09 +0000 en-US hourly 1 https://wordpress.org/?v=5.1.19 103132298 Get excited and make things with science http://eatyourgreens.org.uk/archives/2010/06/get-excited-and-make-things-with-science.html Fri, 25 Jun 2010 00:30:46 +0000 http://eatyourgreens.org.uk/?p=631 Continue reading Get excited and make things with science]]> Last weekend, 19th & 20th June 2010, saw the first Science Hack Day at the Guardian offices in London. Jeremy Keith organised a venue, food and drink and sponsorship for around 100 people to spend two days building small science projects. Saturday morning saw a series of short talks to introduce the event,  give people some ideas of what they might make, and what tools were available to help them make it. 24 hours of hacking and building followed, with presentations and prizes for the best hacks on Sunday afternoon. Ed Gomez has a great write-up of the hack day itself, and the winning hacks. My personal favourites were the Aurorascope, which shows auroral activity by lighting up LEDs inside a ball representing the Earth, and Random Orbit, a RESTful service to track satellites in real time.

I was asked by Jeremy to give one of the talks at the beginning of the hack day, so I chatted a bit about the work we’ve done with astrometry.net to tag Flickr photos with their celestial locations — astrotagging.

Introducing astrotags

At the Royal Observatory, Greenwich, we’ve set up a Flickr group for our photography competition, Astronomy Photographer of the Year. Photos in the group are being scanned by the astrometry.net bot, which identifies stars in a photo then solves for celestial coordinates by comparison with a reference catalogue. Astrometry.net leaves a comment on each photo, listing the coordinates of the image and the names of objects within the field of view. The comments are relatively easy to parse, and I’ve written a small utility to extract information from commented photos. However, this is the sort of problem that’s ideally suited to machine tags so we asked astrometry.net to add tags to photos in our group using the astro: prefix. The tags are:

astro:RA
Right Ascension of the centre of the photo.
astro:dec
Declination of the centre of the photo.
astro:orientation
Orientation of the photo from North, in degrees.
astro:fieldsize
Angular extent of the photo, East-West × North-South.
astro:name
Named objects in the field. One tag per name.

Some good examples of tagged photos are:

The simplest way to get at these machine tags and use them in your own applications is with YQL, which allows you to query the flickr search and photo info APIs using a simple, SQL-like syntax. To make life easier, I’ve written a YQL open table, flickr.photos.astro, which can be queried to return a feed of astronomical coordinates and info for a set of Flickr photos.

select * from flickr.photos.astro where astro_name = 'Horsehead Nebula'

That query, for example, returns a feed of photos tagged astro:name=’Horsehead Nebula’. For some other examples, have a look at my post on searching astro:name with YQL.

My hack

Astrometry.net have solved almost 7,000 photos on Flickr, but only around 600 of those have been tagged with astro: machine tags. For my hack, I decided to try making a YQL table based on screen-scraping Flickr for information left by the astrometry.net robot. I took the code from my astrotagging web form and put together flickr.photos.astrometry, a YQL open table that can parse astrometry information from Flickr comments. The input parameter is a Flickr photo page URL, so a query looks like

select * from flickr.photos.astrometry where url = 'http://www.flickr.com/photos/dangerous_astro/4722913544/'

This returns a feed of the coordinates and names found on that page.

To demo this, I hacked together a little javascript astronomy photo search engine. You pass in a search query in the URL:

http://eatyourgreens.org.uk/yql/scihackday.html?text=milky+way

That text is then used to run a Flickr search and grab up to 30 photos, shown as thumbnails. The search is limited to photos which have been solved by astrometry.net, and we also request the photographer’s name so that we can credit them:

select * from flickr.photos.search(30) where text = 'milky way' and extras='owner_name' and machine_tags = 'Astrometrydotnet:status=solved'

If you don’t pass in a search query, we instead return the 30 most recent photos solved by astrometry.net.

select * from flickr.photos.search(30) where extras='owner_name' and machine_tags = 'Astrometrydotnet:status=solved'

When you select a thumbnail, by clicking on it, another YQL query is run against flickr.photos.astrometry to return the coordinates and names for that photo. The coordinates are used to plot the photo on a map of the sky, while the names are listed as links so that you can go on to search for pictures of specific objects in the field of view.

It’s quite a simple little bit of code, but hopefully it shows how useful YQL can be for accessing structured data on the web, even when that data is in HTML or plain text. If anyone does use it to build anything, Astronomy Photographer of the Year has a showcase page for mashups built using the Flickr astrometry data.

]]>
631
Generating astrotags for Flickr photos http://eatyourgreens.org.uk/archives/2010/01/generating-astrotags-for-flickr-photos.html http://eatyourgreens.org.uk/archives/2010/01/generating-astrotags-for-flickr-photos.html#comments Sun, 03 Jan 2010 12:46:06 +0000 http://eatyourgreens.org.uk/?p=603 Continue reading Generating astrotags for Flickr photos]]> In December, I talked at London Web Standards about tagging astronomy photos with position and name information. I mentioned that around 400 photos have been tagged already on Flickr but this is only a tiny fraction of the 4,900 photos that have been solved by astrometry.net. It would be great if the remaining 4,500 photos could also be tagged, and it ought to be straightforward to generate tags for those photos too. Inspired by the iNaturalist Taxonomic Tagging Tool, I’ve written a little astrotagging form for Flickr photos.

When the astrometry.net robot solves a photo on Flickr, it leaves a comment identifying the coordinates of the photo and listing the names of objects in the field.

Hello, this is the blind astrometry solver. Your results are:
(RA, Dec) center:(82.4668973542, 6.33857270637) degrees
(RA, Dec) center (H:M:S, D:M:S):(05:29:52.055, +6:20:18.862)
Orientation:161.45 deg E of N

Pixel scale:67.93 arcsec/pixel

Parity:Reverse (“Left-handed”)
Field size :53.14 x 39.85 degrees

Your field contains:
The star Rigel (βOri)
The star Betelgeuse (αOri)
The star Aldebaran (αTau)
The star Bellatrix (γOri)
The star Alnilam (εOri)
The star Alhena (γGem)
The star Alnitak (ζOri)
The star Saiph (κOri)
The star Mintaka (δOri)
The star Cursa (βEri)
IC 2118 / IC 2118 / Witch Head nebula
NGC 1976 / NGC 1976 / Great Nebula in Orion / M 42
NGC 1990 / NGC 1990
IC 434 / IC 434 / Horsehead nebula
IC 443 / IC 443
NGC 2264 / NGC 2264 / Christmas Tree cluster / Cone nebula

View in World Wide Telescope

—–
If you would like to have other images solved, please submit them to the astrometry group.
Posted 3 weeks ago. ( permalink | delete )

These comments are always in the same format, so it’s straightforward to parse them and extract the astrometry metadata as a list of tags. I’ve written a small form which does this, using YQL to grab the comments from a Flickr photo then parsing them using standard DOM traversal and manipulation methods.

If you have a photo which has been solved, generating tags is straightforward. Copy the address of a Flickr photo page into the tagging form and press the big blue ‘Get astrotags’ button. The script should find the comment from astrometry.net and print out the tags for celestial coordinates and names, which you can then paste into the ‘Add a tag’ form on Flickr.

The code to do this is fairly simple, and reproduced below. After initialising the page, we can take advantage of YQL’s HTML parser to fetch all of the comments for a Flickr photo page by selecting all paragraphs inside divs with a class of ‘comment-content’ at that URL.

select * from html where url='http://www.flickr.com/photos/eatyourgreens/4182924966/' and xpath='//div[@class="comment-content"]/p'

We then loop through the results of this query, looking for paragraphs which contain the text ‘blind astrometry solver’. If we have a match, we add this paragraph to the DOM so we can parse it with standard DOM methods. The code then loops through the child nodes of the comment paragraph, running regular expression matches against any text nodes it finds to extract the coordinates of the photo.

Names are slightly more tricky. For those, we grab every line of text between ‘Your field contains:’ and the line ‘—–‘ above the signature, strip out whitespace, split each line on ‘/’ to get individual names and store these in an associative array, keyed on name to remove duplicates. That done, we can then just loop through the arrays of coordinates and names and print them out.

Here’s the full code:

 var url = "http://www.flickr.com/photos/skiwalker79/4174398309";
 var comment_holder;
 var position_output;
 var names_output;
 
 function init() {
   var url_input = document.getElementById('photoURL');
   var url_button = document.getElementById('updateURL');
   
   comment_holder = document.getElementById('comment');
   position_output = document.getElementById('position');
   names_output = document.getElementById('names');
   
   url_input.disabled = false;
   url_input.value = url;
   url_button.disabled = false;
   position_output.disabled = false;
   names_output.disabled = false;
   
   addEvent(url_button, 'click', function(e) {
     getFlickrPhotoComments(url_input.value);
     return false;
   });
   addEvent(url_input, 'focus', function(e) {
     url_input.select();
   });
   addEvent(position_output, 'focus', function(e) {
     position_output.select();
   });
   addEvent(names_output, 'focus', function(e) {
     names_output.select();
   });
   
   // Mark up nodes which this script updates as
   // ARIA live regions.
   comment_holder.setAttribute('aria-live', 'polite');
   position_output.setAttribute('aria-live', 'polite');
   names_output.setAttribute('aria-live', 'polite');
   
   getFlickrPhotoComments(url);    
 }

 function getFlickrPhotoComments(url) {

   // YQL query to get all comments from a Flickr photo page.
   var yql = "select * from html where url='"+url+"' and xpath='//div[@class=\"comment-content\"]/p'";
   var yql_url = 'http://query.yahooapis.com/v1/public/yql?q='+escape(yql)+'&format=xml&callback=getAstrometryComment&diagnostics=false';
   position_output.value = '';
   names_output.value = '';
   comment_holder.innerHTML = 'Looking up '+url;
   makeYQLRequest(yql_url);
 }
 
 function makeYQLRequest(yql_url) {
   var script=document.getElementById('yqlscript');
   var newscript=document.createElement('script');
   newscript.type = 'text/javascript';
   newscript.src=yql_url;
   newscript.id='yqlscript';
   document.getElementsByTagName("body")[0].removeChild(script);
   document.getElementsByTagName("body")[0].appendChild(newscript);
 }

function getAstrometryComment(data) {
  var results = data.results;
  
  var comment = 'Sorry, that photo has not been solved by <a href="http://astrometry.net">astrometry.net</a>.';
  for (var i in results) {
    var text = results[i];
    // Comments left by the solver contain the text 'blind astrometry solver'.
    if(text.match(/blind astrometry solver/gi)) {
      comment = text;
    }
  }
  parseComment(comment);
  
}

function parseComment(comment) {
  var astro = {};
  var names = {};
  var parsing_names = false;
  
  comment_holder.innerHTML = comment;
  var children = comment_holder.firstChild.childNodes;
  
  for (var i in children) {
    var child = children[i];
    var text = '';
    text = child.data;
    
    if (text) {
      if (text.match(/(RA, Dec)/g) && text.match(/degrees/g)) {
        text=text.match(/[-0-9\.]+/g);
        astro.RA = text[0];
        astro.Dec = text[1];
      } else if (text.match(/Orientation/g)) {
        text = text.match(/[-0-9\.]+/g);
        astro.orientation = text[0];
      } else if (text.match(/Pixel scale/g)) {
        text = text.match(/[0-9\.]+/g);
        astro.pixelScale = text[0];
      } else if(text.match(/Field size/g)) {
        text = text.match(/[0-9\.]+ x [0-9\.]+ (degrees|arcminutes|arcseconds)/g);
        astro.fieldsize = text[0];
      } else if(text.match(/Your field contains:/g)) {
        parsing_names = true;
      } else if (text.match(/-----/g)) {
        parsing_names = false;
      }

      if (parsing_names) {
        names = addNames(names, text);
      }
      
    }
  }

  renderPositionTags(astro);
  
  renderNameTags(names);
  
  if (astro.RA) {
    position_output.focus();
  }
}

function addNames(names, text) {
  
 text = trim(text);
 text = text.split('/');
 for (var j in text) {
   var name = text[j];
   name = trim(name);
   if (name && name !='Your field contains:'){
     names[name] = name;
   }
 }
 return names;
}

function renderPositionTags(astro) {
  
  position_output.value = '';
   for (var tag in astro) {
     position_output.value += 'astro:'+tag+'="'+astro[tag]+'" ';
   } 
}

function renderNameTags(names) {

  names_output.value = '';
   for (var name in names) {
     names_output.value += 'astro:name="'+name+'" '
   }
}

function trim(text) {
  // Trim leading and trailing whitespace from a string.
  text = text.replace(/^\s+/, '');
  text = text.replace(/\s+$/,'');
  return text;
}

function addEvent(obj, evType, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(evType, fn, false);
    return true;
  } else if (obj.attachEvent) {
    var r = obj.attachEvent("on" + evType, fn);
    return r;
  } else {
    return false;
  }
}
]]>
http://eatyourgreens.org.uk/archives/2010/01/generating-astrotags-for-flickr-photos.html/feed 4 603
Searching astro:name with YQL http://eatyourgreens.org.uk/archives/2009/12/searching-astroname-with-yql.html http://eatyourgreens.org.uk/archives/2009/12/searching-astroname-with-yql.html#comments Sat, 19 Dec 2009 22:59:53 +0000 http://eatyourgreens.org.uk/archives/2009/12/searching-astroname-with-yql.html Continue reading Searching astro:name with YQL]]>

Searching astro:name with YQL, originally uploaded by Eat your greens!.

The YQL team announced personal URLs for queries this week. I’ve used the new feature to set up a shortcut for looking up photos of astronomical objects by name. The URL is:

http://queries.yahooapis.com/v1/public/yql/eatyourgreens/astrolookup?name=M+42

You can set the name parameter in the URL to change the name of the object you are looking for. I’ve also set up a demo page to render results from this query. The URL is:

http://eatyourgreens.org.uk/testapps/yql/astronamesearch.html?name=Horsehead+nebula

Again, change the name parameter in the URL to lookup different objects. Note that it looks for an exact match with the astro:name machine tag, so looking up stars is cumbersome:

http://eatyourgreens.org.uk/testapps/yql/astronamesearch.html?name=the+star+deneb+(αcyg)

Update: it seems Flickr’s machine tag search can match just the first part of a tag, so you can search for stars by supplying the first part of the tag’s value.

http://eatyourgreens.org.uk/testapps/yql/astronamesearch.html?name=the+star+deneb

I’ve also made some changes to flickr.photos.astro in order to enable faster searching by name. Use astro_name in a query to find objects by matching on astro:name:

select * from flickr.photos.astro where astro_name = 'M 31'

or use text to run a Flickr text search across photo descriptions and titles:

select * from flickr.photos.astro where text = 'orion'

If you want to see what values have been used for astro:name on Flickr, I recommend Paul Mison’s excellent machine tag browser.

]]>
http://eatyourgreens.org.uk/archives/2009/12/searching-astroname-with-yql.html/feed 1 545
London web standards: Introducing astrotags http://eatyourgreens.org.uk/archives/2009/12/london-web-standards-introducing-astrotags.html http://eatyourgreens.org.uk/archives/2009/12/london-web-standards-introducing-astrotags.html#comments Tue, 15 Dec 2009 00:18:37 +0000 http://eatyourgreens.org.uk/?p=530 Continue reading London web standards: Introducing astrotags]]> Here are the slides from my talk at the December LWS meetup – Introducing astrotags: astrometry, machine tags and YQL (20MB pdf). The examples and demos should all be in the YQL category on this blog.

If you’re interested in the nuts and bolts of the automated astrometry robot, I recommend having a look at astrometry.net and reading Making the sky searchable: Fast geometric hashing for automated astrometry.

]]>
http://eatyourgreens.org.uk/archives/2009/12/london-web-standards-introducing-astrotags.html/feed 2 530
Searching the sky with YQL Execute http://eatyourgreens.org.uk/archives/2009/05/searching-the-sky-with-yql-execute.html Mon, 11 May 2009 22:45:42 +0000 http://eatyourgreens.org.uk/?p=411 Continue reading Searching the sky with YQL Execute]]>

Astro location search with YQL execute, originally uploaded by eat your greens.

I was fortunate enough to win one of the prizes at Open Hack London this weekend. I ported the javascript from my astronomy photo browser to YQL Execute, creating a new open data table which returns celestial coordinates for astrotagged flickr photos. Essentially, my hack extends the flickr API to, hopefully, enable location-based searching in the sky.

Since I only wrote my hack in about an hour, during breakfast on Sunday, I returned to it this evening and finished it off. I’ve defined an open data table at http://eatyourgreens.org.uk/yql/flickr.photos.astro.xml which returns all machine tag info in the astro: namespace for the 50 most recently tagged photos. For convenience, it also returns the photo owner, title, url and root url for thumbnail images.

There is a demo, where you can try searching based on Right Ascension and Declination (both expressed in degrees). Please try it out and leave feedback in the comments here.

Demo URL: http://eatyourgreens.org.uk/testapps/yql/locationsearch.html

Example queries

The Carina Nebula

        select * from flickr.photos.astro
        where ra > 155 and ra < 165
        and dec > -65 and dec < -55

The Orion Nebula and surroundings

        select * from flickr.photos.astro
        where ra > 70 and ra < 100
        and dec > -20 and dec < 10

Get lots of photos of Orion (may be slow)

        select * from flickr.photos.astro(0,200)
        where ra > 70 and ra < 100
        and dec > -20 and dec < 10

Find nebulae from the New General Catalogue (names beginning NGC)

      select * from flickr.photos.astro
      where name like 'NGC%'

Find nebulae from the Messier catalogue (names beginning with M )

     select id, title, url, imgroot, username, ra, dec, fov, orientation, name
      from flickr.photos.astro(40)
      where name like 'M %'

Find all photos of the Rosette nebula

      select * from flickr.photos.astro(0,200)
        where name = 'Rosette nebula'

Explicitly declare all the table columns

      select id, title, url, imgroot, username, ra, dec, fov, orientation, name
      from flickr.photos.astro
]]>
411
Building a KML feed with YQL and coldfusion http://eatyourgreens.org.uk/archives/2009/04/building-a-kml-feed-with-yql-and-coldfusion.html http://eatyourgreens.org.uk/archives/2009/04/building-a-kml-feed-with-yql-and-coldfusion.html#comments Fri, 24 Apr 2009 09:46:21 +0000 http://eatyourgreens.org.uk/archives/2009/04/building-a-kml-feed-with-yql-and-coldfusion.html Continue reading Building a KML feed with YQL and coldfusion]]>

4 views of Comet Lulin, originally uploaded by eat your greens.

Following on from my javascript photo browser, for viewing astronomy photos in Google sky, I’ve written a feed to display Astronomy Photographer of the Year (APY) photos in Google Earth. The address is http://www.nmm.ac.uk/collections/feeds/apyKML.cfm That link should open in Google Earth. If it doesn’t, add it manually in Google Earth via ‘Add > Network Link’ (some browsers save the KML feed rather than opening it).

If you’re interested in seeing how the feed is generated, have a look at the source code. I’ll also go through the code here to try and explain how it works. I’ve written it in coldfusion, but it should be straightforward to rewrite in any other server-side language.

First we define a YQL query to retrieve 30 photos from the APY Flickr group (group ID 973956@N23). We select only photos tagged with 'astro:RA=' to make sure we only get photos tagged with positions by the astrometry.net robot. We then encode the query in a URL and get the data, as xml, using cfhttp.


<cfset yql = "select farm, server, id, secret, title, urls.url.content, tags.tag.raw
		from flickr.photos.info
		where (tags.tag.raw like 'astro:%')
		and photo_id in (
			select id from flickr.photos.search(30)
			where group_id='973956@N23'
			and machine_tags='astro:RA='
		)
">
<cfset yqlURL = "http://query.yahooapis.com/v1/public/yql?q=#URLEncodedFormat(yql)#&format=xml">
<!--- Get our results as XML for better performance.. --->
<cfhttp url="#yqlURL#" redirect="no" />

The YQL query returns XML that looks something like the following fragment, one photo element, with title and urls, for each returned tag.


<results>
	<photo farm="4" id="3465625670" secret="95d665362f" server="3495">
		<title>M42VMC-NS</title>
		<tags>
		    <tag raw="astro:RA=83.8283780568"/>
		</tags>
		<urls>
		    <url>http://www.flickr.com/photos/36672102@N07/3465625670/</url>
		</urls>
	</photo>
	<photo farm="4" id="3465625670" secret="95d665362f" server="3495">
		<title>M42VMC-NS</title>
		<tags>
		    <tag raw="astro:Dec=-5.41730075227"/>
		</tags>
		<urls>
		    <url>http://www.flickr.com/photos/36672102@N07/3465625670/</url>
		</urls>
	</photo>
	

First we parse the output of the YQL query and create a new structure, photos, which will hold one element for each photo, keyed on photo id. We get an array of photo elements by selecting all the children of query.results and loop through this array. If we are dealing with a new photo id, we store it and create a new photo hash to hold the properties of this photo. At the end of this loop, we aim to have each photo stored as a hash with properties photo.title, photo.url etc. photo.imgroot holds the root URL used to construct links to the thumbnail images on Flickr.


	rawData = XmlParse(cfhttp.FileContent);
	//array of results is now in rawdata.query.results.XmlChildren
	results = rawData.query.results.XmlChildren;
	//fun with Java - arrays are easier to loop through if you use their Iterator object.
	iterator = results.Iterator();
	//photos will hold our parsed photo data
	photos = StructNew();
	//loop through YQL results, parse and store photo data in photos, keyed on photo id.
	while (iterator.HasNext()) {
		result = iterator.Next();
		id = result.XmlAttributes.id;
		if(not structKeyExists(photos, id)) {
			photos[id] = structNew();
			photos[id]['name'] = ArrayNew(1);
			p = photos[id];
			p.title = result.title.XmlText;
			p.url = result.urls.url.XmlText;
			p.imgroot = "http://farm
						#result.XmlAttributes.farm#
						.static.flickr.com/
						#result.XmlAttributes.server#/
						#id#_#result.XmlAttributes.secret#";
		}

Parsing the values of the machine tags requires a little bit of extra work. The values we want are stored in the raw attribute for each tag. We split the value on = to get the tag name and value, then split the tag name on : and discard the namespace prefix. The results are stored in our new photo hash as photo[tagname] = value. astro:name and astro:fieldsize require slightly different treatment from the other machine tags. There may be several astro:name tags in a single photo, so we store photo.name as an array. astro:fieldsize, which may be in degrees, arcmins or arcsecs, is converted to x and y values in degrees and stored in photo.fov.x and photo.fov.y.


		tag = result.tags.tag.XMLAttributes.raw;
			//split machine tag name and value
			tmp = ListToArray(tag, '=');
			//discard namespace from tag name by splitting tmp[1] on :
			// store data as o[predicate] = value eg. o[id].RA = 85.123456
			tagname = ListToArray(tmp[1],':');
			tagname = tagname[2];
			if (tagname eq 'name') {
				ArrayAppend(p['name'],tmp[2]);
			} else {
				p[tagname] = tmp[2];
			}
			//fieldsize is a string in degrees, arcminutes or arcseconds.
			//We will standardise on a value in degrees.
			if (tmp[1] eq 'astro:fieldsize') {
			//convert fieldsize string into a numeric value in degrees.
				tmp = ListToArray(p.fieldsize,' ');
				p.fov = structNew();
				p.fov.x = tmp[1];
				p.fov.y = tmp[3];
				if (tmp[4] eq 'arcminutes') {
					p.fov.x = p.fov.x/60;
					p.fov.y = p.fov.y/60;
				}
				if (tmp[4] eq 'arcseconds') {
					p.fov.x = p.fov.x/3600;
					p.fov.y = p.fov.y/3600;
				}
			}
		}

Having parsed the YQL results into a more manageable array of photos, the final step is loop through the photos and generate latitude, longitude, range, rotation and field boundaries for each that we can use in a KML photo overlay. Equations for latitude, longitude and range are taken from Sky data in KML. Unfortunately, there isn’t much documentation explaining the boundaries of photo overlays, but I found by trial and error that we can set the north–south distance to our vertical field in degrees. The east–west distance is the horizontal field corrected by a factor of cos(lat). Note that this works regardless of whether north–south is vertical or horizontal in the photo.


//for each photo, convert machine tag values into numbers used by Google Earth overlays.
		for (id in photos) {
			p = photos[id];
			p.lat = p.Dec;
			p.long = p.RA - 180;
			beta = max(p.fov.x,p.fov.y) * 6.28/360;
		    p.range = 1.5 *6378000 *(1.1917536 * sin(beta/2) - cos(beta/2) + 1);
			p.rotation = 180-p.orientation;
			latField = p.fov.y;
			longField = p.fov.x/cos(p.lat * 6.28/360);
			p.north = p.lat + latField/2;
			p.south = p.lat - latField/2;
			p.east = p.long + longField/2;
			p.west = p.long - longField/2;

		}

That done, we can generate a KML feed by looping through the photos array and printing the photo properties into the appropriate elements of a KML template.


	<?xml version="1.0" encoding="UTF-8"?>
	<kml xmlns="http://www.opengis.net/kml/2.2" hint="target=sky">
	  <Document>
	  <name>Astronomy Photographer of the Year</name>
	  <cfloop collection="#photos#" item="id">
	  <cfoutput>
	    <GroundOverlay>
		<name>#XMLFormat(photos[id].title)#</name>
		<color>b8ffffff</color>
	    <LookAt>
	      <longitude>#photos[id].long#</longitude>
	      <latitude>#photos[id].lat#</latitude>
	      <altitude>0</altitude>
	      <range>#photos[id].range#</range>
	      <tilt>0</tilt>
	      <heading>#photos[id].rotation#</heading>
	    </LookAt>
		<Icon>
			<href>#photos[id].imgroot#.jpg</href>
		</Icon>
		<LatLonBox>
			<north>#photos[id].north#</north>
			<south>#photos[id].south#</south>
			<east>#photos[id].east#</east>
			<west>#photos[id].west#</west>
	        <rotation>#photos[id].rotation#</rotation>
		</LatLonBox>
	</GroundOverlay>
	    </cfoutput>
	   </cfloop>
	  </Document>
	</kml>

A quick footnote about performance. My first version of this code got the YQL results as JSON, but I found that decoding the JSON response was taking around 30 or 40s. Parsing XML, on the other hand, takes around 2 or 3s. So I switched to XML even though the code for processing the XML results was somewhat uglier. I think this is down to CFJSON’s decode function making heavy use of regular expressions, which slows it right down when dealing with large or complicated JSON responses.

]]>
http://eatyourgreens.org.uk/archives/2009/04/building-a-kml-feed-with-yql-and-coldfusion.html/feed 1 349
Ada Lovelace Day – Prof. Linda S. Sparke http://eatyourgreens.org.uk/archives/2009/03/ada-lovelace-day-prof-linda-s-sparke.html Mon, 23 Mar 2009 20:34:18 +0000 http://eatyourgreens.org.uk/?p=332 Continue reading Ada Lovelace Day – Prof. Linda S. Sparke]]> A couple of months ago, I signed the following pledge over at findingada.com:

“I will publish a blog post on Tuesday 24th March about a woman in technology whom I admire but only if 1,000 other people will do the same.”

Well, more than 1,500 people signed up to do the same, so this post is dedicated to Linda Sparke. Why do I admire Linda? Well, firstly, she studies gravitational dynamics, building computer models of the structure and motion of entire galaxies. In fact, she wrote the undergrad textbook on galactic dynamics. Secondly, she also currently dominates the first page of Google for “remarkable warped and twisted”, which I think is an admirable achievement all by itself. Finally, what’s not to admire about someone whose contact details say “knock three times and give the password: F = G m1 m2/ r2“?

On a more personal note, back in 1989 I answered a note from Linda on the noticeboard in the Physics Department at Manchester University inviting final year students to apply for the PhD program in Astronomy at the University of Wisconsin-Madison. Consequently I spent 6 years in the UW-Madison Astronomy department, studying and working with some lovely people, including Linda, and eventually got my own PhD. So thanks Linda! May you continue to inspire people to study astronomy for years to come.

]]>
332
Google sky photo browser http://eatyourgreens.org.uk/archives/2009/03/google-sky-photo-browser.html http://eatyourgreens.org.uk/archives/2009/03/google-sky-photo-browser.html#comments Sun, 15 Mar 2009 19:13:51 +0000 http://eatyourgreens.org.uk/archives/2009/03/google-sky-photo-browser.html

Google sky experiment, originally uploaded by eat your greens.

Just a brief update on my previous post. I’ve now hacked together an astronomy photo browser which displays Flickr photos directly in Google Sky. Requires you to have the Google Earth plugin installed.

]]>
http://eatyourgreens.org.uk/archives/2009/03/google-sky-photo-browser.html/feed 1 328
Mapping the sky with YQL and astrometry.net http://eatyourgreens.org.uk/archives/2009/03/mapping-the-sky-with-yql-and-astrometrynet.html http://eatyourgreens.org.uk/archives/2009/03/mapping-the-sky-with-yql-and-astrometrynet.html#comments Sun, 08 Mar 2009 17:15:04 +0000 http://eatyourgreens.org.uk/?p=300 Continue reading Mapping the sky with YQL and astrometry.net]]>

Machine tags and Google Sky, originally uploaded by eat your greens.

Astronomy photographer of the year has been open for a couple of months now, and the astrophoto Flickr group has a few hundred photos now. The amazing astrometry.net bot has been scanning the group and about 70 photos have been tagged with their celestial coordinates, using astro: machine tags.

Flickr is one of the data sources available for use in YQL. Here’s a YQL query to grab the astro: tags for a photo if you know its Flickr id.

select tags.tag.raw from flickr.photos.info
where photo_id='3330304396' and tags.tag.raw like 'astro:%'

The Google Earth plugin allows you to display an interactive map of the night sky on a  web page and supports the Google Earth API too. Have a look at barnabu.co.uk for some great examples, including a planetarium. Since the YQL query above returns tags containing the celestial coordinates of a flickr photo, those coordinates can be passed to the Google Earth plugin to display the same area of the night sky. Here’s an example for the Horsehead Nebula in Orion. View the source code to see how the astronomical coordinates are parsed from the YQL data and sent to the plugin.

That’s good if we know the id of a single photo. What if we want to display all the photos from the astrophoto group that are tagged with astro:RA (the celestial equivalent of geo:long)? The YQL query to grab the photo details and astro: tags for multiple photos is more involved, using a join to get the photo ids, but still quite straightforward.

select farm, server, id, secret, title, urls.url.content, tags.tag.raw from flickr.photos.info
		where (tags.tag.raw like 'astro:%')
		and photo_id in (
			select id from flickr.photos.search(30)
			where group_id='973956@N23'
			and machine_tags='astro:RA='
		)

Here’s an image gallery generated using that YQL query. Click on the photo thumbnails to change the sky view. Again, you can view the source code to see the javascript that generates the gallery. The code needs improvement but hopefully demonstrates how the YQL query results are parsed and stored in an array of photos, keyed on the photo ids.

Finally, if we know exactly which photos we want to use in our gallery, we can replace the inner select with a list of id numbers.

select farm, server, id, secret, title, urls.url.content, tags.tag.raw from flickr.photos.info
		where (tags.tag.raw like 'astro:%')
		and photo_id in (
			2955988513, 2970415185, 2796500688
		)

Here’s a looping slideshow, based on that query, which moves through a series of photos of our Milky Way galaxy, from to in .

If you want to find out more about the machine tags that we’re using in the astrophoto group, I wrote a brief introduction for developers on the Royal Observatory web site.

]]>
http://eatyourgreens.org.uk/archives/2009/03/mapping-the-sky-with-yql-and-astrometrynet.html/feed 4 300
A flickr badge for Astronomy Photographer of the Year http://eatyourgreens.org.uk/archives/2009/01/a-flickr-badge-for-astronomy-photographer-of-the-year.html Sat, 24 Jan 2009 15:50:00 +0000 http://eatyourgreens.org.uk/?p=245 Continue reading A flickr badge for Astronomy Photographer of the Year]]> After a discussion at work about promoting Astronomy Photographer of the Year, I had a look at Chris Heilmann’s unobtrusive flickr badge and hacked it very slightly to display the latest favourites from the competition.

View the Astronomy Photographer of the Year group on flickr.

If you would like to add a badge to your own pages, you will need the CSS file fjb.css and the slightly modified script fjb.js. Chris gives instructions for using the badge.The only change I’ve made is to add a parameter, feedUrl, to the settings at the beginning, which contains the full URL of the flickr feed that you want to display. If you want to change this to a different feed, remember you want the JSON feed, not RSS, so make sure the feed URL ends in format=json.

]]>
245