Monthly Archive for Febrero, 2009

A muerte con el mapa

Soy una leyenda. Me refiero a que posiblemente sea la persona más torpe a la hora de desplazarse que puede haber a este lado de tierra. Ni con el GPS del iPhone (sí, tengo un iPhone desde hace poco), ni con las indicaciones de Google Maps. Ni siquiera con las indicaciones por las que voy mendigando…

Vale, odio los mapas. Y soy una verdadera mierda a la hora de situarme, tengo el don de liarla siempre. Mi madre me lo dice, ’sólo tú puedes hacerlo hijo’. No se equivoca. ¿Debería sentirme orgulloso o preocuparme por ello, doctor?

Pero no es mi vida de lo que vengo a hablar, por quién me habéis tomado… Es que he vuelto a enfadarme con Google Maps. Bueno, ahora mismo no, pero sí hace unos meses y ahora que he retomado un poco el jugueteo con el API de Google Maps, es como tomarse mal una CocaCola. Vuelve y jode mucho.

Al turrón. Desde hace relativamente poco (bueno, ya hace bastante que está implementado) se puede usar el API de reverse geocoding desde JavaScript. Es sencillo: creas un nuevo objeto en plan geocoder = new GClientGeocoder(); y llamas a la función getLocations del mismo objeto.

Por dar un ejemplo:

geocoder = new GClientGeocoder();
geocoder.getLocations(latlng, function(addresses) {
if(addresses.Status.code != 200) {
alert("Ubicación no reconocida");
} else {
if(typeof(addresses.Placemark[0].AddressDetails.Country.
\
AdministrativeArea.SubAdministrativeArea.Locality.PostalCode) == "undefined") {
alert("No hemos podido obtener el código postal de este área, con lo que es posible que los resultados de tus búsquedas sean inexactos");
} else {
cp = addresses.Placemark[0].AddressDetails.Country. \

AdministrativeArea.SubAdministrativeArea.Locality.PostalCode. \
PostalCodeNumber;
};
};
);

(Nota mental: vaya pesadilla poner código en WordPress… Donde hay un \ hay que volver a juntar el código (quitando espacios, claro))

Todo este código asume que ya tienes un objeto llamado “latlng” que contiene las coordenadas de Latitud y Longitud que quieres convertir a código postal en este caso. Crear el objeto LatLng es muy fácil: latlng = new GLatLng(latitud, longitud);.

Aunque así parezca fácil, obtener la información reversa no es nada fácil, entre otras por que cambia el resultado si estás haciendo un reverse de un lugar en España, Alemania, Francia o Estados Unidos (jerarquía e informaciones algo diferentes). Por aquí hay un ejemplo básico de qué resultados da el Reverse Geocoding en XML.

Desde JavaScript, es algo así: del objeto se saca un array, matriz, tupla, quillostoquéeh de ‘PlaceMark’. Aquí asumimos el primero que es teóricamente el más preciso si no es el único. Dentro tenemos “AddressDetails”. Dentro de esto, “Country”. Dentro de “Country”, llega “AdministrativeArea”. Dentro “SubAdministrativeArea”. Dentro, “PostalCode”. Y ahí, finalmente, “PostalCodeNumber”.

Pese a que todo esto es y parece una pesadilla, obtener la dirección sin más se puede conseguir de una forma un poco más sencilla: addresses.Placemark[0].address;

Y repitiéndome de otras veces, esto no deja de ser una chuleta. Tamaño XL, pero sí… lo es.

Voy a ver si me pongo a hacer una aplicación sencillita para el iPhone, con el API de 11870. Mi idea era simplemente rellenar una “posición actual” con texto libre, pasarlo a coordenadas y pasarlo a reverso para confirmar en limpio (por código postal y dirección) la inserción realizada. Una vez ahí, un formulario de búsqueda libre que simplemente deje buscar a una distancia de nuestra posición actual (el API de 11870 permite búsquedas geográficas, la verdad es que mola un montón).

Voy a ver si no me pierdo demasiado (y de nuevo) con el GeoCoding. No es lugar para desorientados.

(Nota de pie: Sí, estoy copiando un poco –mucho– a Gafeman y su Comil.us, que por cierto, funciona genial y está muy bien –si no lo has hecho, échale un ojo–… pero le tengo ganas al API de Google Maps y a la de 11870, sólo sea por programar un poco para la plataforma webapp-móvil y exprimir al máximo el API JavaScript de Google Maps sin usar los propios mapas).

Para el futuro

Otro tanto de furilo, compañía y La Coctelera. Acaban de sacar su último proyecto llamado “Las cinco del día“. Cinco noticias, un amago de resumen del día. Según dicen, lo que tendría sentido recordar dentro de 50 años. Me recuerda bastante a 20palabras, que como otros proyectos web se extinguió (a estas alturas del juego, caballeros, sabemos que nada es para siempre). Promete y mucho. A ver qué nos da, que eso es otra cosa. ¡Suerte!

PHP: estirar el objeto

No, nada. Es un maldito título no-creativo. En realidad yo venía a hablar de mi libro a hablar del tema de extensión infinita de objetos clases. En algunos lenguajes de programación se pueden crear objetos e ir extendiéndolos hasta el infinito y más allá, no es el caso de PHP.

Por poner un ejemplo: si tenemos una clase que es AllTheApplication, es posible que queramos que herede las clases ApplicationRenderPage y ApplicationDatabase, algo como:

class ApplicationRenderPage {}
class ApplicationDatabase {}
class AllTheApplication extends ApplicationRenderPage, ApplicationDatabase {}

Sin embargo, esto no está (todavía) disponible en PHP por lo que nos dará un error. Eso no significa que no se puedan hereder cualidades de un objeto en tercer grado:

class ApplicationRenderPage {}
class ApplicationDatabase extends ApplicationRenderPage {}
class AllTheApplication extends ApplicationDatabase {}

En este último caso, AllTheAplication podría manejar también funciones y variables no protegidas tanto de ApplicationRenderPage como de ApplicationDatabase. Voilà!

Y una pequeña nota: aunque esto sea de cierta forma una solución posible, estoy casi seguro de que hay formas más consistentes de hacerlo, puesto que en este caso las clases se van extendiendo una a otra, de cierta forma ‘en anillo’ con lo que conlleva al hacer cambios en la estructura. Recomendaría algo parecido a:

class ApplicationRenderPage {}
class ApplicationDatabase {}
class AllTheApplication { function __construct() { $this->ApplicationDatabase = new ApplicationDatabase; $this->ApplicationRenderPage = new ApplicationRenderPage; } }

Así, basta con inicializar el objeto ($Application = new AllTheApplication) y de ahí acceder a los subobjetos (echo $Application->ApplicationDatabase->QueryCount si tenemos una variable que se llame QueryCount dentro del objeto ApplicationDatabase inicializado desde el construct de AllTheApplication). Ojo, no es oro todo lo que reluce y en este caso no se pueden acceder a las variables entre los distintos objetos (quizás usando parent::ApplicationDatabase, aunque no sé demasiado como se comportaría).

Y esto, señores, es una chuleta.

Maldito seas, Murphy

De la saga de ‘programadores desamparados’, o más bien jodidos y precedido por el post ‘Probabilidades‘ (de que cambien Twitter cuando peor te va), llega el ‘es que lo estás haciendo mal’.

No, no hablo de ninguna crítica pelotera (que haberlas, haylas), si no de la putada que supone pasarse 2 horas currando en una verdadera chorrada. No por eso, si no por el empacho que te metes después de cruasáns con miel, así andamos…

El módulo APC tiene una función (RFC1867) que básicamente permite mostrar una barra de carga de archivo en entornos que tengan el caché APC activado. Más o menos una linea asín en el formulario:

<input type=”hidden” name=”APC_UPLOAD_PROGRESS” value=”<?php echo uniqid() ?>” />

Pues bien, si tenemos un input ‘file’ para subir el archivo, tendrá que ir debajo del input oculto ‘APC_UPLOAD_PROGRESS’, por qué si no no funcionará la barra de progreso.

Obviamente si lo digo… sí, lo he hecho. 2… dos malditas horas para darme cuenta. Murphy, te odio.

PS: saludos a Aguarate, que le hace ilusión… ¬¬”