Mar 012015
 
Artículo PHP

Factual es una base de datos georeferenciada de lugares, servicios y puntos de interés accesible gratuitamente a través de un interfaz de programación de aplicaciones (API).

En este artículo se explica cómo utilizar una librería PHP para acceder a esta base de datos, y las características del contenido que se puede obtener de la misma.

Obtención de las claves de acceso

Aunque es gratuito, las consultas a la base de datos de factual requieren autentificación OAuth. Por lo tanto, necesitamos obtener un par de claves de acceso.

Para ello, accedemos al sitio web de factual, y pulsamos sobre GET STARTED > GET API KEY

obtener-claves-factual

En pantalla aparece un formulario de registro en que que debemos darnos de alta con una dirección de correo y contraseña.

Una vez registrados, seguimos los pasos que se indican en pantalla, hasta obtener la clave:

claves-oauth-factual

En esta pantalla, podemos ver que:

  • El nivel de acceso es free (unverified). Con este nivel de acceso podemos realizas un máximo de 100 consultas diarias. Si lo deseamos, podemos obtener el nivel de acceso free (verified), que también es gratuito, y tiene un límite de 10.000 consultas diarias (Para ello, deberemos dar los datos de una tarjeta de crédito, aunque el servicio sea gratuito)
  • Por otra parte, podemos restringir el acceso a consultas realizadas desde una determina dirección IP o desde un determinado dominio
  • Al solicitar las claves, deberemos indicar las categorías en las que estamos interesados.
  • Por último, en la parte inferior de la pantalla hay enlaces para la descarga de las librerías del API para los lenguajes de programación más habituales, entre los cuales se encuentra el enlace de descarga de la librería PHP.

Descarga de la librería y comprobación de la instalación

Pulsando sobre el enlace de descarga de la librería PHP, accedemos a la página de factual php driver en github.com desde la cual podemos realizar la descarga del fichero factual-php-driver-master.zip (202KB).

Al descomprimirlo, se crea un fichero que contiene todos los scripts que componen la librería. Entre ellos está un script de comprobación de la instalación “test.php”. Ejecutamos el script, pasándole como argumentos las claves OAuth obtenidas previamente. El script realiza una comprobación de todas las funcionalidades requeridas, y a continuación comprueba el acceso a cada uno de los países para los que existe información en la base de datos de Factual:

$ php test.php FACTUAL-KEY FACTUAL-SECRET

Testing Factual
========================
PHP verison v5+                         Pass
No classname conflicts                  Pass
Parse INI File Function                 Pass
SPL is loaded                           Pass
curl is loaded                          Pass
Creating Query object                   Pass
Setting query parameter                 Pass
API Connection                          Pass
Limit/Filter/Sort                       Pass
Unicode Filter                          Fail
Punctuation                             Pass
Quotes Test                             Pass
'In' Filter                             Pass
Multi Filter                            Pass
Geo Search                              Pass
Multi Country Search                    Pass
Response URL                            Pass
Request Table Name                      Pass
Response Headers                        Pass
Response Code                           Pass
Total Row Count                         Pass
Submit Test                             Fail	You do not have access to the requested resource.
Reverse Geocoder                        Pass
Creating Query object                   Pass
Resolve Endpoint                        Pass
Crosswalk Endpoint                      Pass
Schema Endpoint                         Pass
Diffs Test                              Pass	Not Authorized [403], but that's expected'
Checking Argentina                      Pass
Checking Australia                      Pass
Checking Austria                        Pass
Checking Belgium                        Pass
Checking Brazil                         Pass
Checking Canada                         Pass
Checking Chile                          Pass
Checking China                          Pass
Checking Columbia                       Pass
Checking Croatia (Hrvatska)             Pass
Checking Czech Republic                 Pass
Checking Denmark                        Pass
Checking Egypt                          Pass
Checking Finland                        Pass
Checking France                         Pass
Checking Germany                        Pass
Checking Greece                         Pass
Checking Hong Kong                      Pass
Checking Hungary                        Pass
Checking India                          Pass
Checking Indonesia                      Pass
Checking Ireland                        Pass
Checking Israel                         Pass
Checking Italy                          Pass
Checking Japan                          Pass
Checking Luxembourg                     Pass
Checking Malaysia                       Pass
Checking Mexico                         Pass
Checking Netherlands                    Pass
Checking New Zealand                    Pass
Checking Norway                         Pass
Checking Peru                           Pass
Checking Philippines                    Pass
Checking Poland                         Pass
Checking Portugal                       Pass
Checking Puerto Rico                    Pass
Checking Russia                         Pass
Checking Singapore                      Pass
Checking South Africa                   Pass
Checking South Korea                    Pass
Checking Spain                          Pass
Checking Sweden                         Pass
Checking Switzerland                    Pass
Checking Taiwan                         Pass
Checking Thailand                       Pass
Checking Turkey                         Pass
Checking United Kingdom                 Pass
Checking United States                  Pass
Checking Venezuela                      Pass
Checking Vietnam                        Pass
========================

Ejemplo de consulta en PHP a la base de datos de Factual.

A continuación, vamos a escribir un pequeño script de ejemplo que realiza una consulta simple. Comenzamos por cargar la librería “Factual.php”, y a continuación creamos un objeto de la clase “Factual”, para lo cual deberemos pasarle como argumentos las claves OAuth que hemos obtenido anteriormente.

 require_once('./factual-php-driver-master/Factual.php');
 $factual = new Factual("FACTUAL-KEY","FACTUAL-SECRET");

A continuación, creamos un objeto de la clase “FactualQuery”, en el que especificaremos los criterios de la consulta que deseamos realizar:

 $query    = new FactualQuery;
 $query->at(new FactualPoint($latitude,$longitude));
 $query->sortAsc("\$distance");

En este ejemplo, vamos a realizar una consulta de lugares cercanos a un punto identificado por su latitud y longitud. En el objeto $query también indicamos que deseamos obtener un resultado ordenado por la distancia al punto indicado.

Por último, realizamos la consulta llamando al método “fetch()” del objeto $factual, al que le pasamos el tipo de objeto que queremos obtener (“places”), y el objeto $query que contiene los criterios de búsqueda:

  $res = $factual->fetch("places", $query);
  $numresults = $res->getTotalRowCount();
  print_r $res->getData();

Si ejecutamos esta consulta habiendo inicializado las variables $latitud,$longitud a (40.417221, -3.703544) (las coordenadas de la Puerta del Sol de Madrid, según Google Maps), obtenemos como resultado un array de veinte entradas, como éste:

Array
(
    [0] => Array
        (
            [address] => Calle del Carmen, 4
            [admin_region] => Comunidad de Madrid
            [category_ids] => Array
                (
                    [0] => 436
                )
            [category_labels] => Array
                (
                    [0] => Array
                        (
                            [0] => Travel
                            [1] => Lodging
                            [2] => Hotels and Motels
                        )
                )
            [country] => es
            [email] => info@hoteleuropa.eu
            [factual_id] => d70dcbfe-6777-44d5-ad83-fd02bd9890c1
            [fax] => 915214696
            [hours] => Array
                (
                    [monday] => Array
                        (
                            [0] => Array
                                (
                                    [0] => 7:00
                                    [1] => 9:00
                                )
                            [1] => Array
                                (
                                    [0] => 13:00
                                    [1] => 17:00
                                )
                            [2] => Array
                                (
                                    [0] => 20:00
                                    [1] => 21:00
                                )
                        )
                    ...

                    [sunday] => Array
                        (
                        ...
                        )
                )
            [hours_display] => Mon 7:00-9:00, 13:00-17:00, 20:00-21:00; Tue 7:00-9:00, 13:00-16:00;
                Wed 7:00-9:00, 14:00-15:00, 18:00-19:00; Thu 7:00-9:00, 13:00-15:00; Fri 7:00-9:00,
                 12:00-16:00, 20:00-21:00; Sat 8:00-23:00; Sun 9:00-11:00, 13:00-15:00, 17:00-20:00
            [latitude] => 40.417188
            [locality] => Madrid
            [longitude] => -3.703572
            [name] => Hotel Europa
            [neighborhood] => Array
                (
                    [0] => Sol
                    [1] => Centro
                    [2] => Cortes
                )
            [postcode] => 28013
            [region] => Madrid
            [tel] => 915212900
            [tel_normalized] => 915212900
            [website] => http://www.hoteleuropa.eu/
            [$distance] => 4.3684826
        )
    ...
    [19] => Array
        (
         ...
        )
)

Como podemos ver, la información disponible para cada entrada del array incluye:

  • Un identificador único de la entrada (“factual_id”)
  • latitud y longitud en las que se encuentra, y distancia al punto especificado en la búsqueda
  • categoría a la que pertenece, en una estructura jerárquica (en el ejemplo, Travel > Lodging > Hotels and Motels
  • Opcionalmente, puede haber información adicional asociada a la entrada. En el ejemplo se incluye el nombre del hotel, dirección, teléfono, email y horario de apertura

Criterios  y parámetros de búsqueda

En el sencillo ejemplo de búsqueda que hemos visto hasta ahora, se solicitaban los lugares alrededor de un punto identificado por sus coordenadas (latitud,longitud), ordenados de menor a mayor distancia. Para ello, hemos utilizado el método at() de la clase FactualQuery.

La clase FactualQuery también incluye métodos para realizar otros tipos de búsqueda, entre los cuales se encuentran:

  • public function within($geo)  – Restringe la búsqueda a registros contenidos en el área $geo (un círculo o un rectángulo) que se le pasa como argumento.
  • public function search($term)  – Permit realizar una búsqueda “Full Text Search”
  • public function limit($limit) – Establece el número máximo de registros que devuelve la consulta. El valor por defecto es 20, y el máximo que se puede establecer es 50
  • public function offset($offset) – Establece el primer registro a partir del cual devolver resultados (para la paginación)
  • public function includeRowCount() –  Incluye en la respuesta el total de registros coincidentes con los criterios de búsqueda utilizados, aunque el número de registros devueltos sea inferior.
  • public function select($fields)  – Permite establecer los campos que debe incluir la búsqueda. Por defecto, se devuelven todos los campos de la tabla “places” (Ver más abajo el apartado “Esquema de la tabla places”)
  • public function field($field) – Permite establecer un criterio de búsqueda basado en los valores de uno de los campos (Ver ejemplo de full text search más abajo)
  • public function sortAsc($field), public function sortDesc($field) – Ordena en orden ascendente o descendente por los valores del campo que se le pasa como argumento.

Ejemplos:

Búsqueda Full Text Search

  $query = new FactualQuery;
  $query->search("Sushi Santa Monica");  //busca el texto en todos los campos de la tabla
  $query->field("country")->equal("US"); //limita los resultados a lugares de Estados Unidos
  $res = $factual->fetch("places", $query);

Búsqueda de un máximo de 10 lugares en un radio de 5Km de un punto dado

	$query = new FactualQuery;
	$query->within(new FactualCircle(34.06018, -118.41835, 5000)); //Círculo con un radio de 5 Km
	$query->limit(10); //Limita a 10 resultados
	$query->sortAsc("\$distance"); //ordena por distancia al punto indicado
	$res = $factual->fetch("places", $query);

Esquema de la tabla “places”

Naturalmente, para establecer algunos de los criterios de búsqueda, debemos saber el nombre de los campos de la tabla “places”. Esto se puede obtener fácilmente realizando una consulta para obtener el esquema de la tabla, de la forma:

  $res = $factual->schema("places");
  print_r($res->getColumnSchemas());

Con esto obtenemos un array con la definición de los 287 campos de los que consta la tabla “places” en el momento de escribir este artículo:

Array
(
    [name] => FactualColumnSchema Object
        (
            [name] => name
            [description] => Business/POI name
            [faceted] =>
            [sortable] => 1
            [label] => Name
            [datatype] => String
            [searchable] => 1
        )

    [address] => FactualColumnSchema Object
        (
            [name] => address
            [description] => Address number and street name
            [faceted] =>
            [sortable] => 1
            [label] => Address
            [datatype] => String
            [searchable] => 1
        )
   ...

Categorías

Cada una de las entradas en la base de datos de Factual está clasifica en una determinada categoría: Restaurantes, Museos, Farmacias,…. La categoría es probablemente uno de los criterios de búsqueda más habituales en una consulta. Por ejemplo, si queremos limitar los resultados para que devuelvan una determinada categoría, establecemos un criterio de búsqueda de la forma:

$query->field("category_ids")->in($category);

En donde $category es el identificador numérico de la categoría deseada (p.ej., 80: Farmacias, 311: Museos,…)

Las categorías están organizadas jerárquicamente. Por ejemplo, la categoría 80 (Farmacias) pertenece a la categoría 62 (Salud), a la que también pertenecen las categorías 69 (Dentistas), 74 (Hospitales y Centros de Salud), etc…

La relación completa de categorías existentes (más de 400) se puede consultar en el enlace:

http://developer.factual.com/working-with-categories/

Es esa misma página podemos también realizar la descarga de la tabla de categorías en formato JSON.

Referencias

Factual API Documentation

 Publicado por en 4:38 pm

 Deja un comentario

(requerido)

(requerido)