Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get Place ID of city from Latitude/Longitude using Facebook API

I need to find the Facebook place for the city for many lat/long points. The actual points refer to personal addresses, so there are no exact place ID's to look for as in the case of a business.

For testing, I was looking for the town of Red Feather Lakes, CO.

  • The graph search function will return a lot of places, but does not return cities Example

  • Raw FQL does not let you search by lat/long, and has no concept of "nearby" anyway. Example

  • An FQL query by ID reveals that there is an least a "Display Subtext" field which indicates that object is a city. Example

Thanks for any help. I have over 80 years of dated and geotagged photos of my dad that he would love to see on his timeline!

EDIT

Cities are not in the place table, they are only in the page table. There is an undocumented distance() FQL function, but it only works in the place table. (Via this SO answer.)

This works:

SELECT name,description,geometry,latitude,longitude, display_subtext 
FROM place 
WHERE distance(latitude, longitude, "40.801985", "-105.593719") < 50000

But this gives an error "distance is not valid in table page":

SELECT page_id,name,description,type,location 
FROM page 
WHERE distance(
  location.latitude,location.longitude,
  "40.801985", "-105.593719") < 50000
like image 673
Stan James Avatar asked Feb 03 '12 03:02

Stan James


2 Answers

It's a glorious hack, but this code works. The trick is to make two queries. First we look for places near our point. This returns a lot of business places. We then take the city of one of these places, and use this to look in the page table for that city's page. There seems to be a standard naming conventions for cities, but different for US and non-US cities.

Some small cities have various spellings in the place table, so the code loops through the returned places until it finds a match in the page table.

$fb_token = 'YOUR_TOKEN';

// Red Feather Lakes, Colorado
$lat = '40.8078';
$long = '-105.579';
// Karlsruhe, Germany
$lat = '49.037868';
$long = '8.350124';

$states_arr  = array('AL'=>"Alabama",'AK'=>"Alaska",'AZ'=>"Arizona",'AR'=>"Arkansas",'CA'=>"California",'CO'=>"Colorado",'CT'=>"Connecticut",'DE'=>"Delaware",'FL'=>"Florida",'GA'=>"Georgia",'HI'=>"Hawaii",'ID'=>"Idaho",'IL'=>"Illinois", 'IN'=>"Indiana", 'IA'=>"Iowa",  'KS'=>"Kansas",'KY'=>"Kentucky",'LA'=>"Louisiana",'ME'=>"Maine",'MD'=>"Maryland", 'MA'=>"Massachusetts",'MI'=>"Michigan",'MN'=>"Minnesota",'MS'=>"Mississippi",'MO'=>"Missouri",'MT'=>"Montana",'NE'=>"Nebraska",'NV'=>"Nevada",'NH'=>"New Hampshire",'NJ'=>"New Jersey",'NM'=>"New Mexico",'NY'=>"New York",'NC'=>"North Carolina",'ND'=>"North Dakota",'OH'=>"Ohio",'OK'=>"Oklahoma", 'OR'=>"Oregon",'PA'=>"Pennsylvania",'RI'=>"Rhode Island",'SC'=>"South Carolina",'SD'=>"South Dakota",'TN'=>"Tennessee",'TX'=>"Texas",'UT'=>"Utah",'VT'=>"Vermont",'VA'=>"Virginia",'WA'=>"Washington",'DC'=>"Washington D.C.",'WV'=>"West Virginia",'WI'=>"Wisconsin",'WY'=>"Wyoming");

$place_search = json_decode(file_get_contents('https://graph.facebook.com/search?type=place&center=' . $lat . ',' . $long . '&distance=10000&access_token=' . $fb_token));
foreach($place_search->data as $result) {
  if ($result->location->city) {
    $city = $result->location->city;
    $state = $result->location->state;
    $country = $result->location->country;
    if ($country=='United States') {
      $city_name = $city . ', ' . $states_arr[$state]; // e.g. 'Chicago, Illinois'
    }
    else {
      $city_name = $city . ', ' . $country; // e.g. 'Rome, Italy'
    }
    $fql = 'SELECT name,page_id,name,description,type,location FROM page WHERE type="CITY" and name="' .$city_name. '"';
    $result = json_decode(file_get_contents('https://graph.facebook.com/fql?q=' . rawurlencode($fql) . '&access_token=' . $fb_token));
    if (count($result->data)>0) {
      // We found it!
      print_r($result);
      break;
    }
    else {
      // No luck, try the next place
      print ("Couldn't find " . $city_name . "\n");
    }
  }
}
like image 129
Stan James Avatar answered Nov 10 '22 07:11

Stan James


I found this solution worked for me when looking for a page for the closest city to the specified latitude/longitude. For some reason LIMIT 1 didn't return the closest city so I bumped up the limit and then took the first result.

SELECT page_id
FROM place
WHERE is_city and distance(latitude, longitude, "<latitude>", "<longitude>") < 100000
ORDER BY distance(latitude, longitude, "<latitude>", "<longitude>")
LIMIT 20
like image 2
Dave Grenier Avatar answered Nov 10 '22 08:11

Dave Grenier