bioneural.net site preferences

Accessibility

Toggle width/ text size:

style

Default/Alternate

Suits visual impairment, mobile devices

Styling

Change the theme:

layout

Sorry, this option is not enabled

Link behaviour

Links with an icon are off-site:

links

Right-click any link to optionally open in a new window or tab


 

Share Twitter locations using Google Maps

With my tweets integrated into WordPress the next challenge was to integrate my Twitter location with my custom Google Map. This recipe uses a WordPress theme functions.php file and the excellent Geo Mashup plug-in for WordPress. One advantage of this method is that you don't need to add custom location tags to each tweet (as you do for example here using Pipes). This method simply reads the location as set in your Twitter profile until you change it (and tweet again).

The code given here tested on Geo Mashup 1.1.3 and WordPress 2.7.1.

Setting your location in Twitter

You can manually update the text of your Twitter profile location on the web via Settings > Account > Location, but an easier way to do this is via a location-aware client such as Tweetie or Twitterrific for iPhone, either of which can optionally update your profile location in conjunction with a tweet:

tweetie.jpg

Alternatively if you want to update your location without tweeting use a client such as Sparrow for iPhone (which will simultaneously update Fire Eagle to the same location):

sparrow.jpg

Note, however, that the following code extracts your location from the Twitter user timeline so you do need to tweet before this method will reflect your new location.

You should be aware of the potential privacy issues around real-time location sharing via services such as Twitter, Yahoo!'s Fire Eagle, and Google's Latitude. Best to keep your location approximate if you publish it at all.

A function to get your location from Twitter

Create the following function in the functions.php file of your WordPress theme:

// Get Twitter location for self
function myTwitLoc() {

	$user = 'username';
	$password = 'password';

	$ch = curl_init("http://twitter.com/statuses/user_timeline/twitterid.xml");
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch,CURLOPT_TIMEOUT, 30);
	curl_setopt($ch,CURLOPT_USERPWD,$user . ":" . $password);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
	curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
	$result = curl_exec ($ch);
	$data = strstr($result, '<?');
	$xml = new SimpleXMLElement($data);
	return $xml->status->user->location;
}

You'll need to replace three variables with your own specific information:

Variable: Replace with:
username The username you use to log in to your Twitter account
password The password you use to log in to your Twitter account
twitterid The number from your Twitter user timeline feed, found by clicking Updates from your Twitter home page (e.g. 15629885)

What this function does after authenticating is return your user timeline (containing your status updates) and parse it to extract the included location information (if present). So if your Twitter profile says your location is "Chesterfield UK" the following code on your Geo Mashup map page would return "Chesterfield+UK":

<?php $xml = myTwitLoc(); _e(urlencode($xml)); ?>

It's quite simple to link this output to Google Maps, like so:

<a href="http://maps.google.com/?q=<?php $xml = myTwitLoc(); _e(urlencode($xml)); ?>">Map</a>

But Geo Mashup can't handle proper name locations as Google Maps can, so we need to geocode the place name into coordinates we can send to our mashup. Initially I had tried to do this via JavaScript (in the plug-in's custom.js file) using GClientGeocoder() and failed, but the Maps API also offers a HTTP geocoding service. To utilize this we need a second function to parse the KML file output by the geocoder:

// Geocode Twitter location for Geo Mashup
function geocodeTwit($location) {
	$ch = curl_init();
	$timeout = 5;
	curl_setopt ($ch, CURLOPT_URL, 'http://maps.google.com/maps/geo?q=' . $location . '&output=xml&oe=utf8&sensor=true&key=myAPIkey');
	curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
	curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
	$geotwit = curl_exec($ch);
	curl_close($ch);
	$xml = new SimpleXMLElement($geotwit);
	list($longitude, $latitude, $altitude) = explode(",",$xml->Response->Placemark->Point->coordinates);
	return "lat=$latitude&amp;lng=$longitude";
}

This time there's only one variable to replace:

Variable: Replace with:
myAPIkey Copy the long string defining your Google Maps API key from Geo Mashup plugin Settings

The geocodeTwit() function has thus extracted the coordinates from the KML file returned by the geocoder, and then re-arranged them in the particular syntax required by the Geo Mashup plugin.

Nearly there. The final step is to pass the location retrieved by the myTwitLoc() to the geocodeTwit() function to build our map link URL. We could add the following to our GeoMashup page (substituting your own domain name/ path to your map page, adjusting the zoom to suit):

<a href="http://mysite.com/map/?<?php $xml = myTwitLoc(); $xml = urlencode($xml); $location = geocodeTwit($xml); _e($location); ?>&amp;zoom=12" title="I last tweeted from <?php $xml = myTwitLoc(); _e($xml); ?>">Where's Wally?</a>

All being well we should end up with a well-formed Geo Mashup URL, something like this (remembering we started with "Chesterfield UK" in Twitter):

http://www.bioneural.net/map/?lat=53.2353575&lng=-1.4241462&zoom=12

This custom URL will centre your Google Map on the location specified in your Twitter profile. It won't place a marker on the map which IMHO is a good thing, since that would imply geo-location accuracy that simply doesn't (and shouldn't) exist.

where.jpg

Try it out here.

Caveat: At the risk of stating the obvious if your Twitter location is null, your map link won't contain coordinates and therefore won't function.

Forget about me—where are my followers?

You can create a function to obtain and plot their locations too (but it might be nice to ask first?). A slight modification of myTwitLoc():

// Get Twitter location for followers
function locateTwits() {

	$user = 'username';
	$password = 'password';

	$ch = curl_init("https://twitter.com/statuses/followers.xml");
	curl_setopt($ch, CURLOPT_HEADER, 1);
	curl_setopt($ch,CURLOPT_TIMEOUT, 30);
	curl_setopt($ch,CURLOPT_USERPWD,$user . ":" . $password);
	curl_setopt($ch,CURLOPT_RETURNTRANSFER,1);
	curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0);
	curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
	$result = curl_exec ($ch);
	$data = strstr($result, '<?');
	$xml = new SimpleXMLElement($data);
	return $xml
}

You can now manipulate the XML file as you choose. For example, to display the Twitter screen name and location of your most recent follower:

<?php $xml = locateTwits(); echo '<a href="http://twitter.com/' . $xml->user[0]->screen_name . '">' . $xml->user[0]->screen_name . '</a> @ ' . $xml->user[0]->location; ?>

Or, grab the location of specific followers and show their profile picture for kicks:

<?php $xml = locateTwits(); echo '<img src="' . $xml->user[5]->profile_image_url . '" /> @ ' . $xml->user[5]->location; ?>

followers.jpg

The rest I leave up to you... get cosy with the API documentation.

Tip: Firefox is great for viewing XML files (Safari strips the tags).

xml.jpg

Other tricks with Twitter locations

In a previous post I shared code to allow readers to tweet your posts. We could also insert an additional code block into the WordPress loop to find <strike>twits</strike> Twitterers geo-located in the vicinity of where your post is geotagged:

Find nearby people using Twitter' . ''; } ?>

nearby_twits_post.jpg

Try it out here.

I also shared code to embed your latest tweets into your WordPress blog using SimplePie. A nice addition might be a link to nearby Twitter users, say within 10km of your profile location. We can create this (independent of Geo Mashup) like so:

<a href="http://search.twitter.com/search?q=near%3A<?php $xml = myTwitLoc(); _e(urlencode($xml)); ?>+within%3A10km" title="Nearby users on Twitter (within 10km)" class="feedlink"><img src="<?php bloginfo('template_directory'); ?>/img/gti-twitter.png" alt="Twitter" /></a> 

nearby_twits.jpg

Try it out here.

Notice I set my home location to "Chesterfield,UK" in Twitter? If set to "Chesterfield UK" or "Chesterfield, UK" Twitter thinks I've found WiFi access in Pocahontas State Park and Forest, Virginia USA. LOL!

Update 01.05.09: Enclosing <?php $xml = myTwitLoc(); _e(urlencode($xml)); ?> within quote entities allows "Chesterfield, UK" with correct punctuation!

<a href="http://search.twitter.com/search?q=near%3A&quot;<?php $xml = myTwitLoc(); _e(urlencode($xml)); ?>&quot;+within%3A10km" title="Nearby users on Twitter (within 10km)" class="feedlink"><img src="<?php bloginfo('template_directory'); ?>/styles/bioneural/gti-twitter.png" alt="Twitter" style="margin-right: 20px;" /></a>  

Credits

Thanks to Dylan Kuhn (Geo Mashup author), Ben Griffiths (PHP help), Jason Gilmore (HTTP geocoding howto), and the Dreamhost Wiki (cURL).

6 responses to Share Twitter locations using Google Maps


  1. 1 dave c

    This is great, very close to what I am looking for:

    I'm trying to find a way to geomap author profile information from a wordpress blog. Any experience with that? It seems like it would be pretty similar. Thoughts?

  2. 2 Bruce

    very close to what I am looking for

    You think so Dave? Sounds a million miles apart, but intriguing nevertheless ;-)

    The main difference is that profile location in Twitter has a standardized XML container; there is no such standard for WordPress blogs (or any other kind). If you had control or sway over the blog(s) you wanted to map then you could enforce a standardized encoding which you could then parse. For example you might have the blog owners use the Geo Mashup plug-in, which could geotag their "about" pages using appropriate meta tags. Another option would be to embed hCard metadata into the about page. If you weren't bothered about accuracy you could use IP address geolocation. And of course, based on the examples above, you could use a service like Twitter to manage location (if it were dynamic) and write this into the about/ profile page using PHP. You could then link this, perhaps using Google's HTTP geocoding service, to either an external Google Map or a global map on your own site, or even to a mini-map embedded right in your about page (again, Geo Mashup does the hard work for you).

    Hope that gives you some ideas. Good luck!

  3. 3 Angelo

    Help! i'm way above my pay grade.

    I've got all of the code put into the functions.php ... I'm using a standard wordpress page and editing the HTML there. I put in [geo_mashup_map] and that all works fine... Not sure what other code goes where. does the key code go in the geo-mashup.php?

    <a href="http://renovosolutions.com/?page_id=20?&zoom=12" title="I last tweeted from ">Where's Wally?

    sigh i'm in a bit over my head. but i'd like to post my exact location so my parents can see where i'm at while i travel, via twitter. any suggestions? email me.

  4. 4 Bruce

    Hi Angelo,

    Looking at your current live code your 'Where's Wally?' hyperlink is malformed. The problem may be that you are trying to pass the page ID to Geo Mashup via use of the ?page_id=20 URL. Let's just recap the steps and use the alternative URL natural-language URL for your map page and base it on the code I am actually using on mine:

    1. Make sure you correctly installed the Geo Mashup plugin, and that you have a Google Maps API key entered in WP Settings > Geo Mashup > Overall > Google Maps Key.

    2. Copy the myTwitLoc() function code block to your theme's functions.php file, replacing the 3 variables as tabulated beneath the code with your own Twitter info.

    3. Copy the geocodeTwit($location) function code block to your theme's functions.php file, replacing the 'myAPIkey' variable as tabulated beneath the code with your own key string from Step 1.

    4. On your map page create your 'Where's Wally?' link (say below the [geo_mashup_map] shortcode) with the following code:

    <a href="http://www.renovosolutions.com/where-am-i/?<?php $xml = myTwitLoc(); $xml = urlencode($xml); $location = geocodeTwit($xml); _e($location); ?>&zoom=12" title="I last tweeted from <?php $xml = myTwitLoc(); _e($xml); ?>">Where am I?</a>

    Optionally, stop at this point. Or, if you want a custom location marker, continue thus:

    5. Append &load_xhair=1 to the URL in the link within Step 4, after the zoom=12 bit.

    6. Borrow xhair.png from my site and upload it to yours.

    7. In custom.js (/plugins/geo-mashup-custom/ if using the current version) paste the following:

    //Add crosshair to Twitter mashup
    if (GeoMashup.opts.load_xhair) {
    	marker_icon = new GIcon();
    	marker_icon.image = "http://renovosolutions.com/images/xhair.png";
    	marker_icon.iconSize = new GSize(64, 64);
    	marker_icon.shadowSize = new GSize(0,0);
    	marker_icon.iconAnchor = new GPoint(32, 32);
    	marker_icon.infoWindowAnchor = new GPoint(16, 16);
    	marker_icon.infoShadowAnchor = new GPoint(16, 16);
    
    	var xhair = new GMarker(map.getCenter(), marker_icon);
    	map.addOverlay(xhair);
    
    	var tabs = []
    	tabs.push(new GInfoWindowTab('Info', "<div class='locationinfo'><h2>Geolocating Angelo...</h2><p >This is the approximate location from which Angelo last tweeted.</p></div>"));
    	tabs.push(new GInfoWindowTab('Photo', "<div class='mugshot'><p>Put your photo here if you like.</p></div>"));
    
    	map.openInfoWindowTabsHtml(map.getCenter(), tabs);
    }

    Make sure this code goes inside the customizeGeoMashupMap (properties, map ) function.

    I hope that is clear. Please let me know how you get on. Good luck!

  5. 5 Sanjay

    How about this approach of actually displaying the location on the twitter message:

    http://twitpic.com/c45ea

  6. 6 Bruce

    @Sanjay not sure what particular advantage that offers. If you mouseover the 'Where's Bruce?' link on my map page you'll see the text name of my location displayed. It's simple to echo that location to display inline on the page, rather than in the hyperlink title, so as to place it along side the most recent tweet—which could be embedded as I've done here. So the above code will achieve this, with only minor rearrangements. A matter of preference perhaps?

Something to say?

Comments may be moderated, are subject to spam filtering, and should be inoffensive and relevant to this post. Please disclose commercial interests.

Usable tags include <a href=""> <blockquote> <em>.