jueves, 26 de febrero de 2015

Javascript para el manejo simple de google maps

Estuve trabajando un poco con google maps en javascript y se me ocurrió hacer un script para trabajar más fácilmente con ello. Aprendí cómo programar en javascript orientado a objetos y lo poco cooperativo que es con google maps pero al final terminé con una clase que maneja los mapas de una forma bastante cómoda.

Quise que fuera simple y que me permitiera mezclar el código que yo quisiera, principalmente quería que la parte de crear el mapa y cosas comunes como agregar marcadores y crear un menú contextual fueran más fáciles.


Para usarlo hay que agregar 3 scripts: gMaps.js, jQuery y el api de google maps. Además hay que agregar el css gMaps_style.css:
        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
        <script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false"></script>
        <script type="text/javascript" src="gMaps/gMap.js"></script>

        <link rel="stylesheet" type="text/css" href="gMaps/gMap_style.css">

Aquí un ejemplo del uso:
Para usarlo primero hay que crear una instancia del mapa:

var mMap = new gMap();

Para agregar marcadores, hay que usar la función addMarker que lleva los parámetros: nombre, latitud, longitud e info:

mMap.addMarker('Nombre', 0, 0, 'Informacion');

La info es el html que va a aparecer cuando se haga click en el markador, se puede ignorar o pasar un string vacío para que no haya info

Para crear un menú contextual primero hay que crear sus items, la función addMenuItem toma el HTML del item y el javascript que se correrá al crearse el menú (opcional). Esto último sirve para agregar un código que se corra al hacer click en el item del menú.

mMap.addMenuItem(itemHTML, itemJavascript);

Dentro del HTML de estos items, si se ingresa :lat: o :lng:, serán cambiados por los valores de latitud y longitud del lugar del mapa donde se hizo click derecho (yo personalmente lo uso para ponerlo en un form y mandarlo usando ajax).
Finalmente se usa la función createContextMenu para crear el menú con los items que se agregaron.

mMap.createContextMenu();

Para terminar se debe crear el mapa usando la función createMap pasándole la id del contenedor, las coordenadas de dónde se debe centrar el mapa y el nivel de zoom.

mMap.createMap("map_canvas", 0, 0, 14);

Tiene que ir al final, sino no se agregarán los marcadores ni el menú contextual.

Para que todo funcione bien, el código debe correrse después de cargarse el html, lo cual ya está programado en la clase gMap. Para agregar código después de la creación del mapa, se usa  la función queue, que pueden usar si quieren para agregar más código al final. Tienen que pasarle una función que lleva un parámetro que es la referencia a la clase.

mMap.queue(function(aRef){});

Si quieren usar variables o funciones de la clase gMap, usan aRef, por ejemplo, si quieren acceder al mapa, usan aRef.mMap.

Por cualquier duda, pueden dejar un comentario. Espero facilitarle un poco la vida a alguien con esto.

viernes, 26 de diciembre de 2014

wxPython - Cargar imágenes en Base64

Otro resultado de usar Tkinter es que me acostumbré a guardar las imágenes en Base64, lo cual me resultó bastante cómodo pero al cambiar a wxPython no encontré una manera directa de cargar las imágenes. Resultó ser muy sencillo pero me llevó un tiempo llegar a esa conclusión:

Esta función toma como argumento una imagen encriptada en Base64 (un string) y devuelve un recurso de wxPython (wx.Bitmap) que se puede usar para mostrar la imagen en pantalla.

Además hice una simple clase que coloca la imagen como un widget en la ventana. La hice para simplificar el proceso ya que suele ser el mismo y le agregué la función Add para que ya se encargue de centrarlo.

La imagen cargada por loadResource se puede usar en otros widgets como wx.BitmapButton, básicamente en cualquier lugar que se pueda usar un bitmap.

Espero ahorrarle a alguien el tiempo que estuve para enterarme de esto (a menos que sea el único que guarda las imágenes en Base64).

sábado, 13 de diciembre de 2014

wxPython - Validar entrada en TextCtrl

Lo que más me motiva a publicar cosas en mi blog es compartir cosas que hice por mi cuenta después de no encontrar cómo hacerlas en internet.

Hace tiempo ya que no publico nada, y en ese tiempo empecé a usar wxPython el cual me está gustando mucho y sin dudas va a reemplazar a Tkinter. Queriendo hacer una entrada que requiera validación (ej: sólo números menores a cierto número) me enteré de que la manera de hacerlo no era tan directa como en Tkinter.

Busqué por ahí y la gente sugería usar el evento EVT_CHAR y revisar que la tecla presionada fuera una que se permitiera pero eso causa problemas principalmente porque hay que poner excepciones para cada tecla de función (como las flechas, ctrl, shift) y no da mucho control sobre lo que se hace. Después de buscar bastante no pude encontrar nada mejor pero llegué a una conclusión: El evento EVT_CHAR se realiza al presionar una tecla y antes de que se agregue al valor del TextCtrl, mientras que el evento EVT_TEXT se realiza al cambiar el contenido y después de que se cambió ese valor. Así que tenemos un evento que se dispara junto antes de cambiar el texto y uno justo después, con eso se puede primero guardar el contenido del TextCtrl y después ver si el texto nuevo cumple con las condiciones y en el caso de que no cumplan, cambiarlo por el texto anterior.

Hice una clase para hacer justamente eso:

La clase asigna las funciones onChar y onChange a los eventos EVT_CHAR y EVT_TEXT respectivamente, onChar guarda en una variable el valor actual del TextCtrl, la función onChange queda vacía para que se cree una para cada validator que se quiera hacer. La función dontAllow() está para cambiar el valor al que estaba previamente, de esa manera el valor no cambia.

Acá hay un ejemplo de una clase que hereda de TextValidator que valida que la entrada sea un número menor a mMaxInt:

Lo único que hay que hacer es agregar mMaxInt al __init__ y crear la función onChange que revisa si el valor nuevo es un número y si es menor al número máximo, en el caso de no serlo, se corre dontAllow() para volver a poner el valor anterior. (en este caso, cuando el valor nuevo es '' (un string vacío), se puede reemplazar por un 0 (cero) si es que se necesita que haya un valor en el TextCtrl)

viernes, 1 de agosto de 2014

Nerd Programming - Mandar mail por Python

Hoy hice una clase de python que hace más fácil enviar eMails, así que decidí compartirla por si a alguien le es de utilidad.
La clase permite acceder a la dirección de mail y enviar todos los mails que se quieran.

Para usarla hay que:
  1. Configurar dirección de mail:
    mail = EMail()
    mail.confMail(eMail-address, password, smtp-server, smtp-port)
  2. Crear nuevo correo:
    mail.newMail(subject)
  3. Agregar texto y/o archivos adjuntos
    mail.addText(text)
    addAttachment(path_to_file)
  4. Enviar correo (este paso se puede repetir por cada receptor):
    mail.send(receiver)
Ejemplo:
from sendEMail import EMail

sender = 'mail@mail.com'
pass = 'password'
smtp = 'smtp.mail.com'
port = 25
receiver = 'mail2@mail.com'
subject = 'Hola!'
adjunto = '/path/to/file'
texto = 'Hola! Este es un mail de prueba.'

mail = EMail()
mail.confMail(sender, pass, smtp, port)
### Lo siguiente se puede repetir por cada mail
mail.newMail(subject)
mail.addText(texto)
mail.addAttachment(adjunto)
mail.send(receiver)
###
mail.close() #Si no se quiere que se pueda usar más mail para acceder a su eMail, se cierra y eso hace que sea necesario correr confMail de nuevo para poder acceder.

Código:


Espero que a alguien le sirva y si tienen dudas, dejen en los comentarios y trataré de responder.

domingo, 27 de abril de 2014

Estoy haciendo un juego - Treasure Break


Para los que todavía no lo saben, estoy estudiando para desarrollar videojuegos y el viernes pasado terminé el alpha de mi primer juego. Se trata de juego basado en el breakout (arkanoid) con elementos del pacman. Mi intención es que el juego se pueda jugar sin saber nada al respecto y sin tutoriales, así que voy a dejar el link para que lo prueben y me comenten sus opiniones:

Related Posts Plugin for WordPress, Blogger...