Christian Heilmann

Newsmap – using Placemaker to add geo location to a news feed

Friday, May 22nd, 2009 at 1:42 am

I am right now very excited about the new Placemaker beta – a location extraction web service released at Where2.0. Using Placemaker you can find all the geographical locations in a feed or a text or a web url and you get them back as an array of places.

As a demo I took the Yahoo News feed and ran it through Placemaker. The resulting places are plotted on a map and the map moves from location to location when you hover over the news items.

The result is online at http://isithackday.com/hacks/placemaker/map.php

Yahoo News Map by  you.

Getting the data from the data feed and running it through placemaker is very straight forward. I explained the basic principle in this blog post on the Yahoo Developer Network blog. The only thing to think about is to define the input and output types correctly:


$key = ‘PASTE YOUR API KEY HERE’;
$apiendpoint = ‘http://wherein.yahooapis.com/v1/document’;
$url = ‘http://rss.news.yahoo.com/rss/topstories’;
$inputType = ‘text/rss’;
$outputType = ‘rss’;
$post = ‘appid=’.$key.’&documentURL=’.$url.
‘&documentType=’.$inputType.’&outputType=’.$outputType;
$ch = curl_init($apiendpoint);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$results = curl_exec($ch);
?>

If you look at the source of this example you will find that Placemaker injected contentlocation elements in the feed itself:


xmlns:georss=”http://www.georss.org/georss” xmlns:cl=”http://wherein.yahooapis.com/v1/cle”
xmlns:xml=”http://www.w3.org/XML/1998/namespace” xml:lang=”en”>

2514815

38.8913
-77.0337


23424793

21.511
-77.8068


23424977

48.8907
-116.982


55843872
Guantanamo, CU]]>
19.9445
-75.1541


You’ll also notice that the elements are namespaced and the names of the locations in CDATA blocks, both things I hate with a passion. Not because they don’t make sense, but because simplexml can be drag to make understand them.

What I wanted to do with this data was twofold: create a JSON array of geo locations to plot on a map and a display of the news content. This is the PHP that does that:


$places = simplexml_load_string($results, ‘SimpleXMLElement’,
LIBXML_NOCDATA);
// if there are elements found
if($places->channel->item){
// start a JSON array
$output .= ‘[‘;
// start the HTML output
$html = ‘‘;
?>

The result of this can be seen here http://isithackday.com/hacks/placemaker/map-2.php.

The JavaScript to show the map is pretty straight forward and more or less the demo example of the maps API:


// will be called with the array assembled in PHP
function placeonmap(o){
// if there are locations
if(o.length > 0){
// create a new geopoints array to hold all locations
// this is needed to determine the original zoom
// level of the map
var geopoints = [];
// add map with controls
var map = new YMap(document.getElementById(‘map’));
map.addZoomLong();
map.addPanControl();
// loop over locations
for(var i=0;i // define a new geopoint and store it in the array
var point = new YGeoPoint(o[i].lat,o[i].lon);
geopoints.push(point);
// create a new marker and give it the unique
// id defined in the PHP. Pop up the title of
// the news item and the name of the location when the
// user hovers over the marker
var newMarker = new YMarker(point,o[i].id);
newMarker.addAutoExpand(o[i].title + ‘(‘+o[i].name+’)’);
map.addOverlay(newMarker);
}

// define best zoom level and show map
var zac = map.getBestZoomAndCenter(geopoints);
map.drawZoomAndCenter(zac.YGeoPoint,zac.zoomLevel);
}

// add a mouseover handler to the list of results
YAHOO.util.Event.on(‘news’,’mouseover’,function(e){
// remove the “news” text of the ID of the current target
// as we named the list items news0 to news19
var id = YAHOO.util.Event.getTarget(e).id.replace(‘news’,’‘);
// if there is still something left we have one of the news
// items
if(id!==’‘){
// get the first marker with the ID we defined in the loop.
var marker = map.getMarkerObject(‘m’+id+’x0’);
// if there is one, pan the map there and show the message
// attached to it.
if(marker){
map.panToLatLon(marker.YGeoPoint);
marker.openAutoExpand();
}

}
});
}

// call placeonmap with the JSON array
placeonmap();

That’s pretty much it. I am sure it can be refined, but it is amazing how easy it is to get geo information into any text with Placemaker.

Tags: , , , , ,

Share on Mastodon (needs instance)

Share on Twitter

My other work: