LinuxParty
Los sitios web que ofrecen servicios basados en la ubicación geográfica son muy populares en Internet. Sitios como Foursquare, Yelp y Google Maps, hacen uso de dónde se encuentra para darle información importante para usted, justo en ese lugar. Usted puede obtener la ubicación de alguien y darles información sobre la base de esa localidad.
En este artículo, se construirá tanto el back end como el front end de una aplicación que utiliza la ubicación GPS para proporcionar el contenido de noticias para el usuario. El back end está escrito en PHP y utiliza MySQL para mantener una lista de artículos y su localización relacionada así como sus coordenadas. La página web de aplicaciones para usuario utiliza los servicios de localización compatibles con los navegadores WebKit para obtener las coordenadas GPS de los usuarios. A continuación, envía las coordenadas al back end de una petición Ajax. El sistema PHP back-end responde con una lista XML de artículos, que el front end renderizará de forma dinámica.
Se utiliza ubicaciones de dos formas diferentes, en este artículo. La primera es cuando se agregan nuevos artículos a la base de datos. Obtienes el back end PHP de una ubicación (por ejemplo, Fremont, CA o Washington, DC), y la página utiliza un servicio de geolocalización proporcionada por Yahoo! para convertir ese lugar en las coordenadas GPS. La segunda manera de utilizar la ubicación es cuando la página web hace una solicitud al navegador para obtener la ubicación del usuario y luego utiliza esa información para consultar la base de datos utilizando Ajax.
La construcción del back end
El código back end se inicia en la base de datos, que en este caso es MySQL. Listado 1 muestra un esquema de la base de datos de una única tabla.
Listado 1. db.sql
DROP TABLE IF EXISTS articles; CREATE TABLE articles( lon FLOAT, lat FLOAT, address TEXT, title TEXT, url TEXT, summary TEXT ); |
La tabla tiene seis columnas, comenzando con la latitud y valores de longitud y la dirección original proporcionado por el artículo (por ejemplo, Fremont, CA). Hay, pues, un poco de información biográfica sobre el artículo, incluido el título, la URL y resumen.
Para construir la base de datos, primero use mysqladmin para crear y luego use el comando mysql para ejecutar el script db.sql:
% mysqladmin --user=root --password=foo create articles % mysql --user=root --password=foo articles < db.sql |
Con la base de datos creada, se puede construir la página PHP que va a utilizar para agregar registros a la base de datos. Listado 2 muestra el código de la página insert.php. (Nota:. El valor de $url en las líneas 5 y 6 debe aparecer como una cadena de caracteres de caracter único, así como dos cadenas más cortas para dotarla de formato.)
Listado 2. Insert.php
<?php $dd = new PDO('mysql:host=localhost;dbname=articles', 'root', ''); if ( isset( $_POST['url'] ) ) { // You need a Yahoo! PlaceFinder application key // Go to: http://developer.yahoo.com/geo/placefinder/ $url = "http://where.yahooapis.com/geocode?q=".urlencode($_POST['address']). "&appid=[yourappid] "; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); $body = curl_exec($ch); preg_match( "/\<latitude\>(.*?)\<\/latitude\>/", $body, $lat ); preg_match( "/\<longitude\>(.*?)\<\/longitude\>/", $body, $lon ); $sql = 'INSERT INTO articles VALUES ( ?, ?, ?, ?, ?, ? )'; $sth = $dd->prepare($sql); $sth->execute( array( $lon[1], $lat[1], $_POST['address'], $_POST['title'], $_POST['url'], $_POST['summary'] ) ); } ?> <html> <body> <form method="post"> <table> <tr><th>Title</td><th><input type="text" name="title" /></td></tr> <tr><th>Summary</th><td><input type="text" name="summary" /></td></tr> <tr><th>Address</th><td><input type="text" name="address" /></td></tr> <tr><th>URL</th><td><input type="text" name="url" /></td></tr> </table> <input type="submit" value="Add Article" /> </form> </body> </html> |
Esta página es una página PHP bastante estándar para insertar registros en una base de datos. En la parte superior, se comprueba si el usuario ha escrito esta página para usted, si es así, se agrega un registro a la base de datos utilizando la biblioteca PDO. En la parte inferior de la secuencia de comandos es un formulario HTML utilizado para introducir los campos.
Lo interesante aquí es en la solicitud al servicio web de Yahoo! utilizando la biblioteca Curl. Para obtener este código, se necesita un ID de aplicación proporcionado por Yahoo! por su servicio PlaceFinder. Para obtener la URL de este servicio, consulte los recursos y el código en el Listado 2 .
El servicio PlaceFinder devuelve una respuesta XML para un lugar determinado. La respuesta incluye la latitud y longitud (más un gran número de bits de información interesante). Una expresión regular simple se utiliza para extraer la latitud y longitud del XML.
Este código está escrito como si una dirección se resuelve siempre a una cota. Si decide utilizar este código en su propio sistema, asegúrese de comprobar si el lugar se devuelve y se presentará un mensaje de error informativo al usuario en caso de que una situación no se resuelva.
Para probar este código, instale la página insert.php en el servidor PHP y usela en en el navegador. Debería ver algo como la forma en la figura 1 .
Figura 1. La forma interactiva artículo
La figura 1 muestra un sencillo formulario web de cuatro campos con los campos de título, resumen, dirección y dirección y un botón para añadir el artículo a la base de datos. La Figura 2 muestra el campo relleno con los valores correspondientes.
Figura 2. El formulario de entrada de población artículo
En la figura 2, los campos se rellenan con el título, el resumen y la dirección URL de un artículo local. La ubicación se especifica como "Fremont, CA" en el campo Dirección. Usted puede especificar una dirección, un código postal, o cualquier otra cosa que se puede resolver en un par latitud / longitud.
En este punto, usted debe llenar la base de datos utilizando la página insert.php con algunos artículos de prensa acerca de su área local. ¿O sólo tiene que utilizar algunos artículos desde cualquier lugar, pero pone en su dirección para que la ubicación GPS de su propio navegador devuelva algún resultado.
Con la base de datos creada y poblada, está listo para generar el servicio de búsqueda que la front end va a utilizar.
Construyendo el servicio de búsqueda
Lo que necesita de un servicio de búsqueda es una página PHP que toma un par de latitud y longitud, a lo largo de un radio, y devuelve los artículos que tienen una ubicación con dicho círculo. El retorno debe ser codificado como XML para una página web (o cualquier otra aplicación) fácilmente se puede leer. El Listado 3 muestra tal página para PHP.
Listado 3. find.php
<?php define( 'LATMILES', 1 / 69 ); define( 'LONMILES', 1 / 53 ); // Change these default coordinates to your current location $lat = 37.3328; $lon = -122.036; $radius = 1.0; if ( isset( $_GET['lat'] ) ) { $lat = (float)$_GET['lat']; } if ( isset( $_GET['lon'] ) ) { $lon = (float)$_GET['lon']; } if ( isset( $_GET['radius'] ) ) { $radius = (float)$_GET['radius']; } $minlat = $lat - ( $radius * LONMILES ); $minlon = $lon - ( $radius * LATMILES ); $maxlat = $lat + ( $radius * LONMILES ); $maxlon = $lon + ( $radius * LATMILES ); $dbh = new PDO('mysql:host=localhost;dbname=articles', 'root', ''); $sql = 'SELECT * FROM articles WHERE lat >= ? AND lat <= ? AND lon >= ? AND lon <= ?'; $params = array( $minlat, $maxlat, $minlon, $maxlon ); if ( isset( $_GET['q'] ) ) { $sql .= " AND name LIKE ?"; $params []= '%'.$_GET['q'].'%'; } $q = $dbh->prepare( $sql ); $q->execute( $params ); $doc = new DOMDocument(); $r = $doc->createElement( "locations" ); $doc->appendChild( $r ); foreach ( $q->fetchAll() as $row) { $dlat = ( (float)$row['lat'] - $lat ) / LATMILES; $dlon = ( (float)$row['lon'] - $lon ) / LONMILES; $d = sqrt( ( $dlat * $dlat ) + ( $dlon * $dlon ) ); if ( $d <= $radius ) { $e = $doc->createElement( "article" ); $e->setAttribute( 'lat', $row['lat'] ); $e->setAttribute( 'lon', $row['lon'] ); $te = $doc->createElement('title'); $te->appendChild( $doc->createTextNode( utf8_encode( $row['title'] ) ) ); $e->appendChild( $te ); $se = $doc->createElement('summary'); $se->appendChild( $doc->createTextNode( utf8_encode( $row['summary'] ) ) ); $e->appendChild( $se ); $ue = $doc->createElement('url'); $ue->appendChild( $doc->createTextNode( utf8_encode( $row['url'] ) ) ); $e->appendChild( $ue ); $ae = $doc->createElement('address'); $ae->appendChild( $doc->createTextNode( utf8_encode( $row['address'] ) ) ); $e->appendChild( $ae ); $e->setAttribute( 'd', $d ); $r->appendChild( $e ); } } print $doc->saveXML(); ?> |
El código parece largo y complicado, pero no lo es. Se puede dividir en dos secciones discretas. En la parte superior, el script ejecuta una consulta que busca todos los artículos dentro de un cuadrado de límite con la latitud y longitud y mín / máx de contenidos en la sentencia SELECT.
La segunda parte del código limita aún más los resultados mediante la iteración a través de cada artículo y la comprobación para ver si está relacionado con el círculo. Es algo de código de trigonometría al principio del bucle foreach. Si cae dentro del círculo, el resultado se añade a un documento XML que se crea y amplía sobre la marcha. El último bit de código sólo imprime el documento XML resultante.
La creación del XML se hace un poco larga, porque todos los nodos que se han creado. Todas las características del artículo, además de la latitud y la longitud se expresan como subnodos de modo que puedan ser de tamaño ilimitado. Este enfoque es particularmente importante en el campo de resumen que es bastante largo, ya que debe contener un resumen del artículo que posee varios párrafos largos.
Para probar el servicio de búsqueda, en primer lugar se debe instalar en el servidor, a continuación, desplácese a ella en el navegador. Debería ver algo como el resultado en la figura 3 .
Figura 3. El XML resultado de find representado en el explorador
La Figura 3 muestra los resultados XML devueltos en el navegador como una especie de página web de clases aunque parece fea, aplastados juntos y carente absoluto de formato. Para ver cómo se ve como XML, seleccione Ver código fuente en el navegador para mostrar algo similar a la figura 4 .
Figura 4. Visualización del fuente del resultado find.php
La Figura 4 muestra el resultado de la consulta en su formato XML original.
Si no ve resultados, hay varios razones posibles. Puede ser que el script no pudiera conectar con la base de datos. Que la localización pudiera ser un problema. Debe cambiar la localización predeterminada en la secuencia de comandos find.php, que debe estar cerca de donde están sus artículos que ha especificado, o usted debe agregar parámetros lat y lon a la URL de la página web. Otra posibilidad es que sus artículos tengan ubicaciones no válidas. Para buscar ubicaciones válidas, inicie sesión en el servidor MySQL y consulte la tabla de artículos usted mismo para ver si los campos de la lat y lon se rellenan adecuadamente.
Suponiendo que el script find.php devuelve algunos resultados, ahora está listo para colocarlo en el front end del sistema.
La construcción de la primera versión de la interfaz de usuario
La primera versión de la interfaz de usuario es muy simple. Se indican las coordenadas GPS desde el navegador, los envía al servidor con un radio de búsqueda no modificable de 20 millas, y luego formatea los datos devueltos para su presentación. Usted puede ver esta primera versión del código en el Listado 4 .
Listado 4. index.php
<html> <head> <script src="/jquery-1.6.1.min.js"></script> <script> $(document).ready(function() { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(successCallback, errorCallback); } else { alert('GPS not supported'); } }); function successCallback(position) { loadArticles( position.coords.latitude, position.coords.longitude ); } function loadArticles( lat, lon ) { $.ajax({ url: "find.php", dataType: 'xml', data: { lat:lat, lon:lon, radius:20 }, success: buildArticlePage }); } function buildArticlePage( data ) { $(data).find("article").each(function() { var title = $(this).find("title").text(); var summary = $(this).find("summary").text(); var url = $(this).find("url").text(); var address = $(this).find("address").text(); $("#output").append( "<a target=\"_blank\" href=\""+url+"\">"+title+"</a><br/>"); $("#output").append( "<i>"+address+"</i><br />"); $("#output").append( summary+"<br /><br />"); }); } function errorCallback(error) { alert('Error getting GPS:'+error); } </script> </head> <body> <div id="output"> </div> </body> </html> |
En el Listado 4 , la parte más interesante del código está en la parte superior del archivo. Una de las primeras cosas que hace el código después de que se carga es buscar navigator.geolocation, a continuación, ejecutar el método getCurrentPosition en él, si es que existe. Este método toma dos parámetros, los cuales son las funciones. La primera función llama si la ubicación se pueden encontrar. El segundo llama si una ubicación no puede ser encontrada.
Cuando una ubicación se encuentra, el successCallback se llama, que a su vez llama loadArticles con las coordenadas especificadas. He separado estas dos llamadas para ayudar con la depuración por si usted tiene algún problema para obtener las coordenadas en su navegador. Usted siempre puede llamar directamente loadArticles con lo que usted elija.
La función loadArticles realiza la petición Ajax al servidor mediante jQuery Ajax. Y el buildArticlePagellama si el servidor web responde con éxito. Puede que tenga que cambiar la URL en loadArticles para apuntar a cualquier lugar find.php que se encuentra en un directorio distinto en esta página.
El buildArticlePage utiliza una serie de llamadas jQuery tanto a través del análisis sintáctico XML y añade nuevas etiquetas HTML para la "producción" de div localizado en la sección del cuerpo del HTML.
Y eso es realmente todo lo que hay que hacer. Créeme, escribiendo la ayuda del GPS en una página web es mucho más fácil de lo que es el uso de las API propietarias para obtener la ubicación en iOS, Android, u otras plataformas. El servicio de geolocalización en caso del navegador admite el seguimiento de la ubicación, si usted espera que cambie rápidamente.
Para probar la página, instale la página index.html en el servidor web y ábralo en el navegador, al igual que en la figura 5.
Figura 5. La página de índice después de recibir los resultados de artículos utilizando las coordenadas GPS
La figura 5 muestra una página web de artículos de la base de datos que se encuentran próximos a la ubicación proporcionada por el navegador web. Antes de ver los datos, es posible que aparezca una advertencia como la de la figura 6 .
Figura 6. La advertencia ubicación Safari pedirá
La figura 6 muestra una advertencia del servidor en dar su ubicación actual en el sitio web. Usted puede optar por aceptar o rechazar según su preferencia, pero para sus propios propósitos pruebe que desea aceptar para que el código JavaScript obtenga las coordenadas, realice la llamada Ajax, y haga los resultados.
Si usted ve un error "GPS no admitido", está utilizando un navegador que no usa webkit, probablemente Microsoft ® Internet Explorer ®. Al momento de escribir este artículo, Internet Explorer no es compatible con servicios de localización.
Si todo funciona, pero no se obtienen resultados, el radio de búsqueda de veinte millas podría ser demasiado pequeño. Basta con modificar el área a 2000, y usted debe comenzar a ver algunos resultados, asumiendo, por supuesto, que usted pone algunos datos en la base de datos en el mismo continente que su ubicación.
El paso final de este artículo es actualizar a tener un control de radio.
Mejora de la interfaz de usuario
Para agregar un control de radio a la página, agregue una etiqueta <select> a la página con opciones para cada uno de los valores de radio que desea soportar. A continuación, añada algo de código jQuery para controlar el valor del control de radio y para actualizar la página, como se muestra en el Listado 5.
<html> <head> <script src="/jquery-1.6.1.min.js"></script> <script> var startLan = null; var startLon = null; $(document).ready(function() { $('#radius').change( function() { loadArticles( startLan, startLon ); } ); if (navigator.geolocation) { navigator.geolocation.getCurrentPosition(successCallback, errorCallback); } else { alert('GPS not supported'); } }); function successCallback(position) { loadArticles( position.coords.latitude, position.coords.longitude ); } function loadArticles( lat, lon ) { startLan = lat; startLon = lon; $.ajax({ url: "find.php", dataType: 'xml', data: { lat:lat, lon:lon, radius:$('#radius').val() }, success: buildArticlePage }); } function buildArticlePage( data ) { $('#output').empty(); $(data).find("article").each(function() { var title = $(this).find("title").text(); var summary = $(this).find("summary").text(); var url = $(this).find("url").text(); var address = $(this).find("address").text(); $("#output").append( "<a target=\"_blank\" href=\""+url+"\">"+title+"</a><br/>"); $("#output").append( "<i>"+address+"</i><br />"); $("#output").append( summary+"<br /><br />"); }); } function errorCallback(error) { alert('Error getting GPS:'+error); } </script> </head> <body> <select id="radius"> <option value="5" selected>5</option> <option value="15">15</option> <option value="50">50</option> <option value="150">150</option> </select> <div id="output"> </div> </body> </html> |
En el Listado 5, los cambios comienzan en la parte superior de la página en la que se añade un listener en el control de radio. Este código invoca entonces los loadArticles cuando el control se cambia. Para hacer el código más simple, el método loadArticles almacena la última ubicación de modo que pueda volver a utilizar cuando el radio se cambia. La sección de HTML de la página también se actualiza para agregar la etiqueta <select> y las opciones de radio.
Para probar las mejoras, instale primero la página web actualizada en el servidor como index2.html y desplácese a ella en el navegador web. Usted debe ver una pantalla similar a la Figura 7 .
Figura 7. La página de búsqueda ahora con un control de radio
La Figura 7 muestra los listados de artículo, junto con un nuevo radio control desplegable en la parte superior de la página. Cambie este dinámico control de radio reconstuida la página para volver a ejecutar la petición Ajax con el valor del radio actualizada. A continuación, se vacía la etiqueta <div> salida y agrega la nueva serie de artículos encontrados. En el caso de la Figura 8, que cambió el valor a 150.
Figura 8. Los resultados de búsqueda para 150 millas
Se puede ver algunos resultados adicionales en la Figura 8 añadido a la parte inferior de la página.
Conclusión
Los servicios de localización como Foursquare, Yelp y Google Maps son populares porque la gente quiere saber lo que es bueno en su área local, y quieren conectarse a sitios próximos. Con esta API, un poco de PHP, jQuery JavaScript, un poco de XML, y algún apoyo en la localización en el navegador web, usted tiene una aplicación web habilitada para la ubicación. El uso de este código como punto de partida, puede construir su propio servicio basado en localización con su propio modelo de datos. Y si su aplicación requiere una alimentación continua de datos de ubicación del cliente, los servicios de geolocalización permiten todavía más servicios de posibilidades que no vamos a indicar aquí, pero puedes escribir algo tu en los comentarios.
Learn
- Yahoo! PlaceFinder service: Turn addresses into latitude/longitude coordinate pairs.
- Geocoding (Wikipedia): Visit a great page on geocoding, which is the process of turning addresses into latitude and longitude pairs.
- W3C Geolocation API Specification (Editor's Draft, February 2010): Check out this specification for the geolocation service in the browser.
- jQuery library: Visit this excellent website that documents all of its features and all of the available extensions.
- The PHP site: Explore the best reference for PHP that's available.
- The W3C: Visit a great site for standards, in particular the XML standard is relevant to this article.
- More articles by this author (Jack Herrington, developerWorks, March 2005-current): Read articles about Ajax, JSON, PHP, XML, and other technologies.
- New to XML? Get the resources you need to learn XML.
- XML area on developerWorks: Find the resources you need to advance your skills in the XML arena. See the XML technical library for a wide range of technical articles and tips, tutorials, standards, and IBM Redbooks
- IBM XML certification: Find out how you can become an IBM-Certified Developer in XML and related technologies.
- developerWorks technical events and webcasts: Stay current with technology in these sessions.
- developerWorks on Twitter: Join today to follow developerWorks tweets.
- developerWorks podcasts: Listen to interesting interviews and discussions for software developers.
- developerWorks on-demand demos: Watch demos ranging from product installation and setup for beginners to advanced functionality for experienced developers.
-
Internet
- La muerte lenta del hipervínculo
- Cómo cambiar dirección IP (modo gráfico), por qué querría hacerlo y cuándo no debería hacerlo
- 10 comandos "IP" útiles para configurar interfaces de red
- Cómo configurar conexiones IP de red usando 'nmcli' en Linux
- Configuración de una IP Estática en una Tarjeta de Red en Linux.
- ¿Migrar a la nube? Marque esta lista de verificación
- Nuevo estándar de Internet L4S: el plan silencioso para hacer que Internet se sienta más rápido
- Nextcloud y Roundcube se Fusionan para Impulsar la Descentralización en la Productividad en la Nube
- Los 10 mejores servidores proxy inversos de código abierto para Linux
- Una guía para principiantes para crear conexiones (Bonding) y puentes de red (Bridging) en Linux
- Conectar dos redes Locales alejadas creando de un Puente Transparente
- Crear un puente de red transparente "bridge" para conectar dos redes locales remotas
- Crear un Puente de Red o Bridge
- La propuesta de la ICANN / Verisign permitiría a cualquier gobierno confiscar nombres de dominio
- Listado errores HTTP, estados de respuesta del servidor