How to programmatically find the continent from a given city or state

I recently ran across a somewhat unusual problem. I needed to find a programatic way to convert a string that could be a city or a state name into the continent that the city or state belongs to. I Googled around a bit and couldn’t find an obvious solution, so I thought I’d write this up in hope of helping the next guy.

What I ended up doing is using the Yahoo! GeoPlanet API. This allowed me to do a query of my city or state name and get a place resource, then use that to find the continent that the place resource belongs to.

So first things first, you’re going to need an app id from Yahoo!, so if you don’t already have one you’ll need to get one. Then you just need to make a request like the following:
http://where.yahooapis.com/v1/places.q(CITY_OR_STATE)?appid=YOUR_APP_ID
Where CITY_OR_STATE is the query term you’re searching for and YOUR_APP_ID is the Yahoo! app id from above. Then you’ll get back something like the following:


<places xmlns="http://where.yahooapis.com/v1/schema.rng" xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:start="0" yahoo:count="1" yahoo:total="300">
<place yahoo:uri="http://where.yahooapis.com/v1/place/2488042" xml:lang="en-US">
<woeid>2488042</woeid>
<placeTypeName code="7">Town</placeTypeName>
<name>San Jose</name>
<country type="Country" code="US">United States</country>
<admin1 type="State" code="US-CA">California</admin1>
<admin2 type="County" code="">Santa Clara</admin2>
<admin3/>
<locality1 type="Town">San Jose</locality1>
<locality2/>
<postal/>
<centroid>
<latitude>37.338470</latitude>
<longitude>-121.885788</longitude>
</centroid>
<boundingBox>
<southWest>
<latitude>37.117840</latitude>
<longitude>-122.160027</longitude>
</southWest>
<northEast>
<latitude>37.555859</latitude>
<longitude>-121.535393</longitude>
</northEast>
</boundingBox>
<areaRank>6</areaRank>
<popRank>12</popRank>
</place>
</places>

You want to grab the woeid (in this case 2488042) for the next part. Next, we need to lookup the continent this place resource belongs to. To do this we make a request like so:
http://where.yahooapis.com/v1/place/THE_WOEID/belongtos.type(29)?appid=YOUR_APP_ID
Where THE_WOEID is the woeid we found in the last step (2488042 in this example) and YOUR_APP_ID is your app id again. This should return something like the following:

<places xmlns="http://where.yahooapis.com/v1/schema.rng" xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:start="0" yahoo:count="1" yahoo:total="1">
<place yahoo:uri="http://where.yahooapis.com/v1/place/24865672" xml:lang="en-US">
<woeid>24865672</woeid>
<placeTypeName code="29">Continent</placeTypeName>
<name>North America</name>
</place>
</places>

Where North America is clearly what we want to pull out of it.

I was doing this in PHP, so here’s a quick and dirty PHP example:

function continent_lookup( $search ) {
    if ( strlen( $search ) == 0 )
        return false;

    $search = urlencode( $search );

    $app_id = 'YOUR_APP_ID';

    $res = file_get_contents( "http://where.yahooapis.com/v1/places.q($search)?appid=$app_id" );
    preg_match( "/<woeid>([0-9]+?)<\/woeid>/", $res, $match );

    if ( !$match )
        return false;

    $woeid = $match[1];

    $res = file_get_contents( "http://where.yahooapis.com/v1/place/$woeid/belongtos.type(29)?appid=$app_id" );
    preg_match( "/<name>(.+?)<\/name>/", $res, $match );

    return $match[1];
}

Hope this helps someone else out there. Let me know if you have any feedback.

This entry was posted in Code, php and tagged , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *