Twitter Facebook Google + RSS Feed

Cómo obtener la temperatura de la ciudad de la máquina cliente mediante la IP en AS3

0
Flash / Flex / ActionScript

Jueves, 27 de diciembre de 2012 a las 12:53hs por Daniel Bilsky

Acá les traigo un ejemplo de cómo obtener la información de la ciudad y temperatura mediante la IP del cliente en AS3.

Para comenzar se deberá crear un proyecto flash en blanco, de ActionScript3 con la compilación de Flash Player 10.3, dentro del mismo deben crearse 2 TextBox, y deberá ponerse los nombres a los mismos:

Los nombres deben ser: txtCity (como en la imagen de ejemplo) y txtTemp, ambos del tipo Dynamic Text.

Ahora comenzamos con nuestro código FLASH:

Como es costumbre, si bien en algunos casos lo hace automáticamente (con las librerías internas de flash), deberemos agregar manualmente una librería para decodificación de JSON.

import flash.events.Event;
import flash.net.URLLoader;
import com.adobe.serialization.json.JSON;

La librería de JSON es una librería aparte, la misma la pueden descargar de https://github.com/mikechambers/as3corelib/tree/master/src

Para utilizar la misma deberán de copiar la librería JSON.as dentro de una carpeta com/adobe/serializacion/json/ partiendo como carpeta raíz donde tienen el “.swf” resultado;

Es decir si el archivo se encuentra en “C:/Windows/Flash Ejemplo”, entonces el JSON.as deberá estar en “C:/Windows/Flash Ejemplo/com/adobe/serializacion/json/JSON.as

En este ejemplo llegaremos a la temperatura mediante la consumición de algunos servicios de la web que nos devuelven los datos que necesitamos.  Para consumir dichos servicios se deberá utilizar el objeto URLLoader.  Para que se vea más claro utilizaremos un nuevo objeto de estos por cada url a la que llamaremos:

var jsonIP:URLLoader = new URLLoader();
var xmlGeoLoader:URLLoader = new URLLoader();
var xmlCityLoader:URLLoader = new URLLoader();
var xmlWeatherLoader:URLLoader = new URLLoader();

Dimensionaremos objetos globales útiles para nuestro cometido, los cuales se irán llenando con los datos obtenidos de nuestra utilidad:

var MyIP = "";
var MyLat = "";
var MyLong = "";
var MyIdCity = "";

Para comenzar debemos obtener la IP de nuestra máquina.  Para este ejemplo consumiremos un servicio web que nos devuelve la misma:

jsonIP.addEventListener(Event.COMPLETE, jsonGetIP);
jsonIP.load(new URLRequest("http://jsonip.appspot.com/"));

En estas líneas lo que estamos haciendo básicamente es decirle a Flash que:

jsonIP.addEventListener(Event.COMPLETE, jsonGetIP);

Agregue una llamada a una función cuando se complete la carga de la URL

jsonIP.load(new URLRequest("http://jsonip.appspot.com/"));

Se le dice a flash que comience con la carga de la url especificada, en este caso “http://jsonip.appspot.com/”.

La misma nos devolverá los siguientes datos (la ip brindada corresponde a www.google.com.ar):

{"ip": "173.194.42.31", "address":"173.194.42.31"}

Una vez cargada la página, entrará a la función “jsonGetIP”, la misma recuperará la IP de la máquina cliente y procederá con el llamado a nuestro próximo servicio web de obtención de datos:

function jsonGetIP(e:Event):void
{
    var IpINFO:Object = JSON.decode(e.target.data);
    MyIP = IpINFO.ip;
    xmlGeoLoader.addEventListener(Event.COMPLETE, XMLGeo);
    xmlGeoLoader.load(new URLRequest("http://api.ipinfodb.com/v3/ip-city/?key=[ KEY OBTENIDA AL REGISTRARSE]&ip="+MyIP+"&format=xml"));
}

Veamos línea por línea lo que estamos haciendo aquí:

var IpINFO:Object = JSON.decode(e.target.data);

obtenemos la respuesta de la página y la decodificamos con la librería de as3codelib

MyIP = IpINFO.ip;

obtenemos el parámetro ip dentro del json devuelto por la página

En las siguientes líneas, creo que no hace falta aclarar ya que estamos repitiendo la llamada a la URL, solo que en este caso apuntamos a  “http://api.ipinfodb.com/v3/ip-city/?key=[KEY OBTENIDA AL REGISTRARSE]&ip=[IP OBTENIDO]&format=xml

xmlGeoLoader.addEventListener(Event.COMPLETE, XMLGeo);
xmlGeoLoader.load(new URLRequest("http://api.ipinfodb.com/v3/ip-city/?key=[KEY OBTENIDA AL REGISTRARSE]&ip="+MyIP+"&format=xml"));

Como observarán se necesitará una KEY, para obtenerla simplemente se deben registrar en la siguiente página:

http://ipinfodb.com/register.php

Una vez registrado, si entran a la página con la KEY brindada y la IP de ejemplo que estamos utilizando obtendríamos algo como esto:

<Response>
    <statusCode>OK</statusCode>
    <statusMessage/>
    <ipAddress>173.194.42.31</ipAddress>
    <countryCode>US</countryCode>
    <countryName>UNITED STATES</countryName>
    <regionName>CALIFORNIA</regionName>
    <cityName>MOUNTAIN VIEW</cityName>
    <zipCode>94043</zipCode>
    <latitude>37.3861</latitude>
    <longitude>-122.084</longitude>
    <timeZone>-08:00</timeZone>
</Response>

De este XML, lo que utilizaremos en este ejemplo es simplemente la locación geográfica, es decir “Latitud” y “Longitud”, esto sirve para ubicarnos en un mapa como por ejemplo en los mapas de google, algo requerido a la hora de buscar la temperatura de algún lugar, sin depender de si el nombre de la ciudad es correcto o no.

Para realizar esta tarea simplemente debemos recorrer el XML obteniendo el parámetro de nuestro interés:

function XMLGeo(e:Event):void
{
    XML.ignoreWhitespace = true;
    var GeoLocation:XML = new XML(e.target.data);
    MyLat =GeoLocation.latitude;
    MyLong = GeoLocation.longitude;
    xmlCityLoader.addEventListener(Event.COMPLETE, XMLCity);
    xmlCityLoader.load(new URLRequest("http://where.yahooapis.com/geocode?q="+MyLat+"+"+MyLong+"&amp;gflags=R"));
}

Como es costumbre veamos que estamos haciendo aquí línea por línea:

XML.ignoreWhitespace = true;

Le estamos diciendo que al leer el XML, quite los espacios en blanco del valor contenido en los tags, por ejemplo “<timeZone> -08:00”)

var GeoLocation:XML = new XML(e.target.data);

leemos los datos devueltos por la página y los almacena en la variable xml

Acá seteamos las variables globales de latitud y longitud:

MyLat =GeoLocation.latitude;

 

MyLong = GeoLocation.longitude;

Nuevamente llamamos a otro Servicio Web, al cual le brindamos los datos obtenidos. Nos devolverá el Código Identificador de la ciudad brindado por la Api de Yahoo.

La url en este caso es http://where.yahooapis.com/geocode?q=[LATITUD]+[LONGITUD]&gflags=R

xmlCityLoader.addEventListener(Event.COMPLETE, XMLCity);
xmlCityLoader.load(new URLRequest("http://where.yahooapis.com/geocode?q="+MyLat+"+"+MyLong+"&amp;gflags=R"));

Nos devolverá algo como:

<ResultSet xmlns:ns1="http://www.yahooapis.com/v1/base.rng" version="2.0" xml:lang="en-US">
    <Error>0</Error>
    <ErrorMessage>No error</ErrorMessage>
    <Locale>en-US</Locale>
    <Found>1</Found>
    <Quality>99</Quality>
    <Result>
        <quality>87</quality>
        <latitude>37.386025</latitude>
        <longitude>-122.083802</longitude>
        <offsetlat>37.386025</offsetlat>
        <offsetlon>-122.083802</offsetlon>
        <radius>400</radius>
        <name>37.3861 -122.084</name>
        <line1>976 Castro St</line1>
        <line2>Mountain View, CA 94041</line2>
        <line3/>
        <line4>United States</line4>
        <house>976</house>
        <street>Castro St</street>
        <xstreet/>
        <unittype/>
        <unit/>
        <postal>94041</postal>
        <neighborhood>Old Mountain View</neighborhood>
        <city>Mountain View</city>
        <county>Santa Clara County</county>
        <state>California</state>
        <country>United States</country>
        <countrycode>US</countrycode>
        <statecode>CA</statecode>
        <countycode/>
        <uzip>94041</uzip>
        <hash>3B0A1BD8ECAC3499</hash>
        <woeid>12797128</woeid>
        <woetype>11</woetype>
    </Result>
</ResultSet>

De aquí obtendremos el ID de la ciudad, el mismo es el WOEID, para obtenerlo volveremos a hacerlo de la misma manera:

function XMLCity(e:Event):void
{
    XML.ignoreWhitespace = true;
    var City:XML = new XML(e.target.data);
    MyIdCity =City.Result.woeid;
    txtCity.text = City.Result.city;
    xmlWeatherLoader.addEventListener(Event.COMPLETE, XMLTemp);
    xmlWeatherLoader.load(new URLRequest("http://weather.yahooapis.com/forecastrss?w="+MyIdCity+"&amp;u=c"));
}

Aquí la única variante con los casos anteriores es:

txtCity.text = City.Result.city;

Con esto reemplazaremos el texto del TextBox por el nombre de la ciudad

Luego el procedimiento es el mismo, con la diferencia de la URL a llamar, en este caso es:

http://weather.yahooapis.com/forecastrss?w=[WOEID OBTENIDO]&u=c

La misma nos devolverá una XML como lo siguiente:

<rss xmlns:yweather="http://xml.weather.yahoo.com/ns/rss/1.0" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" version="2.0">
    <channel>
        <title>Yahoo! Weather - Mountain View, CA</title>
        <link>http://us.rd.yahoo.com/dailynews/rss/weather/Mountain_View__CA/*http://weather.yahoo.com/forecast/USCA0746_c.html</link>
        <description>Yahoo! Weather for Mountain View, CA</description>
        <language>en-us</language>
        <lastBuildDate>Thu, 27 Dec 2012 4:55 am PST</lastBuildDate>
        <ttl>60</ttl>
        <yweather:location city="Mountain View" region="CA" country="United States"/>
        <yweather:units temperature="C" distance="km" pressure="mb" speed="km/h"/>
        <yweather:wind chill="7" direction="0" speed="0"/>
        <yweather:atmosphere humidity="82" visibility="16.09" pressure="1020.2" rising="1"/>
        <yweather:astronomy sunrise="7:20 am" sunset="4:56 pm"/>
        <image>
            <title>Yahoo! Weather</title>
            <width>142</width>
            <height>18</height>
            <link>http://weather.yahoo.com</link>
            <url>http://l.yimg.com/a/i/brand/purplelogo//uh/us/news-wea.gif</url>
        </image>
        <item>
            <title>Conditions for Mountain View, CA at 4:55 am PST</title>
            <geo:lat>37.39</geo:lat>
            <geo:long>-122.07</geo:long>
            <link>http://us.rd.yahoo.com/dailynews/rss/weather/Mountain_View__CA/*http://weather.yahoo.com/forecast/USCA0746_c.html</link>
            <pubDate>Thu, 27 Dec 2012 4:55 am PST</pubDate>
            <yweather:condition text="Fair" code="33" temp="7" date="Thu, 27 Dec 2012 4:55 am PST"/>
            <description>
                <![CDATA[
                    <img src="http://l.yimg.com/a/i/us/we/52/33.gif"/><br /> <b>Current Conditions:</b><br /> Fair, 7 C<BR /> <BR /><b>Forecast:</b><BR /> Thu - Partly Cloudy. High: 12 Low: 4<br /> Fri - Mostly Cloudy. High: 11 Low: 5<br /> <br /> <a href="http://us.rd.yahoo.com/dailynews/rss/weather/Mountain_View__CA/*http://weather.yahoo.com/forecast/USCA0746_c.html">Full Forecast at Yahoo! Weather</a><BR/><BR/> (provided by <a href="http://www.weather.com" >The Weather Channel</a>)<br/>
                ]]>
            </description>
            <yweather:forecast day="Thu" date="27 Dec 2012" low="4" high="12" text="Partly Cloudy" code="30"/>
            <yweather:forecast day="Fri" date="28 Dec 2012" low="5" high="11" text="Mostly Cloudy" code="28"/>
            <guid isPermaLink="false">USCA0746_2012_12_28_7_00_PST</guid>
        </item>
    </channel>
</rss>

Para finalizar entraremos a la última función de temperatura:

function XMLTemp(e:Event):void
{
    XML.ignoreWhitespace = true;
    var Wheather:XML = new XML(e.target.data);
    var datos:XMLList = Wheather.channel.elements();
    txtTemp.text = String(datos[8].@chill) + " °C";
}

Aquí llenaremos el TextBox de temperatura con el dato del xml.  Como podrán notar utilizamos otra forma de lectura de xml, eso es debido a que el formato del XML es “<yweather:units…”. Si intentan leer el XML de la forma anteriormente utilizada se obtendrá un error.

Se obtendrá un Listado e Objetos XML, con lo cual podremos acceder sin necesidad de especificar un nombre de tag. De esta forma evitaremos complicaciones por el “:

Una vez posicionados en la fila correspondiente, se deberá acceder a la propiedad del nodo, en nuestro caso “chill”.

Todo esto anteriormente dicho se puede observar en las siguientes 2 líneas:

var datos:XMLList = Wheather.channel.elements();

 

txtTemp.text = String(datos[8].@chill) + " °C";

Asignación de la temperatura y concatenación de unidad de medida. Esta unidad es seteada en el WSS.

A continuación les mostraremos todo el código junto:

import flash.events.Event;
import flash.net.URLLoader;
import com.adobe.serialization.json.JSON;

var jsonIP:URLLoader = new URLLoader();
var xmlGeoLoader:URLLoader = new URLLoader();
var xmlCityLoader:URLLoader = new URLLoader();
var xmlWeatherLoader:URLLoader = new URLLoader();

var MyIP = "";
var MyLat = "";
var MyLong = "";
var MyIdCity = "";

jsonIP.addEventListener(Event.COMPLETE, jsonGetIP);
jsonIP.load(new URLRequest("http://jsonip.appspot.com/"));

function jsonGetIP(e:Event):void
{
var IpINFO:Object = JSON.decode(e.target.data);
xmlGeoLoader.addEventListener(Event.COMPLETE, XMLGeo);
xmlGeoLoader.load(new URLRequest("http://api.ipinfodb.com/v3/ip-city/?key=[]&amp;ip="+MyIP+"&amp;format=xml"));
}

function XMLGeo(e:Event):void
{
XML.ignoreWhitespace = true;
var GeoLocation:XML = new XML(e.target.data);
MyLat =GeoLocation.latitude;
MyLong = GeoLocation.longitude;
xmlCityLoader.addEventListener(Event.COMPLETE, XMLCity);
xmlCityLoader.load(new URLRequest("http://where.yahooapis.com/geocode?q="+MyLat+"+"+MyLong+"&amp;gflags=R"));
}

function XMLCity(e:Event):void
{
XML.ignoreWhitespace = true;
var City:XML = new XML(e.target.data);
MyIdCity =City.Result.woeid;
txtCity.text = City.Result.city;
xmlWeatherLoader.addEventListener(Event.COMPLETE, XMLTemp);
xmlWeatherLoader.load(new URLRequest("http://weather.yahooapis.com/forecastrss?w="+MyIdCity+"&amp;u=c"));
}

function XMLTemp(e:Event):void
{
XML.ignoreWhitespace = true;
var Wheather:XML = new XML(e.target.data);
var datos:XMLList = Wheather.channel.elements();
txtTemp.text = String(datos[8].@chill) + " °C";
}

Y para finalizar el resultado obtenido:

 

Espero les haya servido y gustado.

Saludos


0 comentarios »

Deja un comentario

Buscar