Inicio > Aplicación, Delphi, OOP, REST > Hablando del tiempo… (OpenWeatherMap) 1/2

Hablando del tiempo… (OpenWeatherMap) 1/2

viernes, 4 de diciembre de 2015 Dejar un comentario Ir a comentarios
Share Button

clima_gdeHace unos días pensaba en un tema para una nueva entrada del blog.
No tenía ideas, así que como solemos hacer aquí cuando no tenemos de qué hablar, se me ocurrió “hablar del tiempo”… (gracias a Javi desde aquí, que me fue realmente el que me puso en la pista del tema ;-) ).

Pues ya está, decidido, hablemos del tiempo.

Tenía en mente escribir sobre algunas de las novedades de las últimas versiones de RAD Studio y utilizaremos el tema para realizar algunas pruebas y demostrar cómo funcionan. Para ellos y para hablar del tiempo, vamos a utilizar en la entrada OpenWeatherMap.

¿Qué es OpenWeatherMap?

Según la web se describe como, “un servicio que provee de datos del tiempo de más de 200.000 ciudades y de todas las ubicaciones geográficas que se encuentra disponible en la web OpenWeatherMap.org y también a través de API. La idea del servicio está inspirada en OpenStreetMap y Wikipedia que ofrecen la información gratuita y disponible para todo el mundo.”

 APY Key

OpenWeatherMap es un servicuio gratuito y para poder trabajar con él, deberemos crear una cuenta y así acceder a una API Key, que es obligatoria a la hora de realizar peticiones a la web.

Para esta entrada y los ejemplos de código he dado de alta una cuenta gratuíta y he obtenido la siguiente API Key:

278857e8dee51f914026df21d0d40c19

_________________________________________________________________
NOTA (21/01/2021):
Algún usuario del blog ha utilizado esta clave, en lugar de para hacer pruebas, para otros temas, de manera que desde la página de OpenWeatherMap me han informado de un tráfico excesivamente alto y de que se bloqueará esta APIKey cuando lo exceda. Siento que para los que accedéis al blog esta deje de funcionar (a ratos). Si queréis hacer pruebas debréis crear vuestra propia clave.
Desgraciadamente a veces intento facilitar las cosas a los que accedéis a estas entradas, pero hay quien prefiere no seguir las reglas y usar el camino fácil.
_________________________________________________________________

AVISO: Para seguir esta entrada y probar los ejemplos, podéis usar esta clave, pero si váis a programar aplicaciones o vuestros propios ejemplos, os aconsejo que déis de alta vuestra propia cuenta y obtengáis vuestra clave, pues en cualquier momento ésta puede dejar de estar activa.

La explicación completa de cómo utilizar el valor de la «API KEY» lo tenéis en este link.

Acceso a la API

Toda la documentación de la API de OpenWeatherMap está disponible en esta dirección.  Muy clara y muy bien documentada y con multitud de ejemplos que muestran cómo se comporta.

Todas o casi todas las opciones y consultas que podamos necesitar están disponibles y la cantidad de datos y detalles acerca del tiempo que podemos obtener es bastante grande.

Podemos consultar en tiempo en una ciudad o ubicación en este preciso momento, a partir de bastantes datos, pero también predicciones futuras a intervalos de horas o días. Es muy sencillo conocer, por ejemplo, el tiempo que nos espera en los próximos 7 días o la cantidad de precipitaciones o temperatura que hará en las próximas horas.
Los datos que se proporcionan incluyen diversidad de parámetros (a parte de los básicos), como pueden ser todos los referentes a lluvias, viento, nubes, nieve,…

Un ejemplo…

Podemos ver el funcionamiento con un ejemplo sencillo.

Una llamada como lo que os muestro a continuación:

http://api.openweathermap.org/data/2.5/find?&q=Barcelona,es&lang=es&units=metric&APPID=278857e8dee51f914026df21d0d40c19

Nos devolverá (según los parámetros indicados), el tiempo actual en Barcelona (ES), con los mensajes en castellano (lang=es) y en unidades del sistema métrico (units=metric –la alternativa es el Imprerial utilizado en Estados Unidos principalmente). Por defecto, como no hemos expresado nada, se devolverá en formato JSON, aunque también se puede pedir la respuesta en XML.

respuesta1

(acceder a la respuesta como texto)

Aquí podemos ver el resultado de esta consulta.

Las unidades en que están expresados los datos, así como el formato de cada uno de ellos, podéis consultarlo en la Referencia a la API, de la que ya hemos hablado antes.

Obtener tiempo en una ciudad

Podemos obtener el tiempo actual en una ciudad de una forma similar a la que hemos visto en el ejemplo anterior.  También hay otras opciones (interesantes para dispositivos móviles) como por ejemplo, obtener el tiempo en un lugar determinado a partir de las coordenadas GPS.

De esta forma, si obtenemos las coordenadas desde nuestro dispositivo, podemos realizar una llamada similar a esta:

http://api.openweathermap.org/data/2.5/weather?lat=41.390&lon=2.154&APPID=278857e8dee51f914026df21d0d40c19

En este caso la llamada se hace utilizando los valores GPS (lat=41.390&lon=2.154) y en la propia respuesta (en la parte final) podemos ver  la ciudad/país a la que pertenecen dichas coordenadas.


«sys»: {
«message»: 0.0027,
«country»: «ES»,
«sunrise»: 1446531928,
«sunset»: 1446569027
},
«id»: 3128760,
«name»: «Barcelona»,
«cod»: 200
}

Ahora de lo que se trata, es de plasmar esto en una aplicación.

img_jsonVamos a empezar de menos a más, así que la primera versión que vamos a ver está compilada con Delphi 7 (sí Delphi 7, no delphi XE 7). Y veremos que salvo la librería de tratamiento de JSON, mucho código -salvo vistas-) es el mismo que posteriormente vamos a compilar para Windows con una versión 10 Seatle y para móviles, tanto Android como iOS. Así, que ciertamente, si programáis con un poco de «vista», el código que generamos en gran parte puede ser reutilizable en las nuevas plataformas.

Para tratamiento de JSON en verisones antiguas, he utilizado la librería ulkJSON (disponible en Sourceforge), de la que ya he hablado otras veces. Funciona muy bien y es una buena opción si posteriormente tenemos que actualizar, porque como veremos en otra entrada, el tratamiento de una respuesta es bastante similar utilizando esta librería, a realizarlo con la unit JSON que encontraremos en las versiones modernas de delphi (así que la migración luego será poco traumática).

Para una respesta como esta, que es la que obtenemos cuando solicitamos los datos sobre una ciudad:

respuesta_json

(obtener un fichero de texto con la respuesta)

Utilizaremos un código como este:

// Parsea la respuesta de varias ciudades a una estructura que nos ha devuelto la web
function TForm1.ParseTiempoCiudades(AObjResp:TlkJSONobject; var ATiempoObj:TTiempoStruct):Boolean;
var
  i, j, num, index:integer;
  oCityList, OWList:TlkJSONlist;
  oCity, oCoord, oMain, oWind, oWeather:TlkJSONobject;
begin
  // ini
  Result := False;
  // Si no está asignado salimos..
  if not Assigned(AobjResp) then begin
    Exit;
  end;
  // Si hay error no parseamos
  if IsErrorResponse(AObjResp, errCode, ErrMsg) then begin
    Exit;
  end;
 
  // proteccion para el parseo
  try
    // cod. devuelto (datos principales
    ATiempoObj.Cod := errCode;
 
    num := AObjResp.IndexOfName('count');
    if (num <> -1) then begin
      num := GetAsInteger(AObjResp.Field['count'].Value);
    end;
 
    // si no hay ciudades
    if (num = 0) then begin
      MessageDlg('No hay ninguna ciudad que coincida con ese código [nombre,pais].', mtWarning, [mbOK], 0);
      Exit;
    end;
 
    // Ciudades (Lista)
    TlkJSONBase(oCityList) := AObjResp.Field['list'];
    // datos de la primera ciudad
    TlkJSONBase(oCity) := oCityList.Child[0];
    // datos básicos
    ATiempoObj.id := GetAsInteger(oCity.Field['id'].Value);
    ATiempoObj.Name := GetAsString(oCity.Field['name'].Value);
    // Parseo de coordenadas
    TlkJSONBase(oCoord)  	 	:= oCity.Field['coord'];
    ATiempoObj.Coord.Lat	 	:= GetAsFloat(oCoord.Field['lat'].Value);
    ATiempoObj.Coord.Lon	 	:= GetAsFloat(oCoord.Field['lon'].Value);
    // main
    TlkJSONBase(oMain) := oCity.Field['main'];
    ATiempoObj.Main.temp := GetAsFloat(oMain.Field['temp'].Value);
    ATiempoObj.Main.tempmin := GetAsFloat(oMain.Field['temp_min'].Value);
    ATiempoObj.Main.tempmax := GetAsFloat(oMain.Field['temp_max'].Value);
    ATiempoObj.Main.pressure := GetAsFloat(oMain.Field['pressure'].Value);
    ATiempoObj.Main.humidity := GetAsInteger(oMain.Field['humidity'].Value);
    // Viento
    TlkJSONBase(oWind) := oCity.Field['wind'];
    ATiempoObj.Wind.speed := GetAsFloat(owind.Field['speed'].Value);
    ATiempoObj.Wind.deg := GetAsInteger(oWind.Field['deg'].value);
    // Weather
    TlkJSONBase(OWList) := oCity.Field['weather'];
    // array de elementos
    SetLength(ATiempoObj.Weather, OWList.Count);
    // Recorrer la lista de objetos.
    for j := 0 to (oWList.Count - 1) do begin
      // Datos weather
      TlkJSONBase(oWeather) := oWList.Child[j];
      ATiempoObj.Weather[j].id := GetAsInteger(oWeather.Field['id'].Value);
      ATiempoObj.Weather[j].main := GetAsString(oWeather.Field['main'].Value);
      ATiempoObj.Weather[j].desc := GetAsString(oWeather.Field['description'].Value);
      ATiempoObj.Weather[j].icon := GetAsString(oWeather.Field['icon'].Value);
    end;
 
    Result := True;
  except
    // si hay error, FALSe
    Result := False;
  end;
end;

Para probar el acceso al servicio, las peticiones básicas y la librería para «parsear» la respuesta JSON, he realizado una aplicación en Delphi. Debajo podéis ver la compilación en Delphi 7  y Delphi Seatle (en el segundo caso se aplican algunos de los nuevos estilos que vienen para Windows 10). Salvo eso, el resto de código es el mismo para ambas compilaciones.

TiempoAtmosferico

Os adjunto el video de Youtube con la versión de Delphi Seatle.

Por último os dejo los links de ambos proyectos, de las librerías y de alguna cosa más relacionada.

Para la siguiente entrada dejo las aplicaciones desarrolladas para plataforma móviles y alguna cosita más.

____________________________________________________________________
UPDATE (13/10/2020):
Peter estudiante de «the hydrometeorological institute», me adjunta este link sobre una comporativa de 8 APIs para obtener datos meteorológicos. El artículo está en la página de climacell, y tal y como comentan al principio no son objetivos, ya que una de las APIs comentadas es suya. De todas formas y teniendo esto presente, creo que la información y los links que aporta en su interior puede ser relevante para alguien que esté pensando en realizar un proyecto de este tipo.
Las 8 mejores API’s meteorológicas para 2020
Gracias Peter.
____________________________________________________________________

Como siempre, cualquier comentario o sugerencia será bienvenido.

Vota este post
Categories: Aplicación, Delphi, OOP, REST Tags:
Subscribe
Notify of
guest

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

13 Comments
Inline Feedbacks
Ver todos los comentarios
Ciro
Ciro
8 years ago

Muchas Felicidades señor neftali, por las grandes iniciativas y guías que nos proporciona.. en lo personal lo admiro.. saludos desde bolivia..

Jose A.
8 years ago

Muy buen artículo (como siempre). Con unas pocas modificaciones se puede adaptar fácilmente para la API de Weather Underground (es el que uso yo normalmente), que tiene ademas la posibilidad de acceder en vivo a los datos de muchas estaciones meteorológicas (suelen ser de gente que pone a disponibilidad del público las datos de sus estaciones).

Javier P.
Javier P.
8 years ago

El análisis de comportamiento del ejecutable con virustotal me dice que hay una inyección de código en dwwin.exe ¿que opinas?
===============
Created processes
C:\WINDOWS\system32\drwtsn32 -p 1496 -e 228 -g (successful)
Code injections in the following processes
dwwin.exe (successful)
=================
Con Windows 8.1 me da un aviso : «el archivo podría dañar mi pc- ¿Está seguro que quiere ejecutarlo?

Casimiro
Casimiro
8 years ago

Espectacularmente claro. Se hace sencillísimo gracias a tus explicaciones paso a paso.
Saludos.

Shirley
7 years ago

Es interesante ver que el código fuente (con ligeros cambios) sea compatible con Delphi7 y con la penúltima versión Delphi Seatle, y entre ambos haya más de 13 años.
Neftalí, gracias por compartir, tus aportes son fantásticos, sigo tus comentarios desde que egresé de la UAB… y desde entonces hace ya 16 años.
Gracias por todos tus comentarios desde entonces :)
Un cordial saludo.

Alex Kain
7 years ago

Los links de descarga estan caidos, error 404.

jaime
jaime
3 years ago

Jose A. :
Muy buen artículo (como siempre). Con unas pocas modificaciones se puede adaptar fácilmente para la API de Weather Underground (es el que uso yo normalmente), que tiene ademas la posibilidad de acceder en vivo a los datos de muchas estaciones meteorológicas (suelen ser de gente que pone a disponibilidad del público las datos de sus estaciones).

hola podrias poner el código adaptado a Wunderground, tengo una estación metereológica en casa que usa este sistema, pero no consigo adaptarlo

13
0
Would love your thoughts, please comment.x
()
x