- EL CONOCIMIENTO ES Y DEBE SER LIBRE -

sábado, junio 26, 2010

Primeros Pasos con Google Maps Api para GWT

Hoy tratare de mostrar un poco del Api de Google Maps para GWT, en realidad los ejemplos que vienen con la Api son bastante explicativos, pero acá mostrare un pequeño vistazo. El ejemplo que muestro lo realice íntegramente con GWT nativo.

¿Cómo muestro un mapa con Google Maps Api para GWT?
 Para insertar un mapa de Google Maps tienes que solicitar un API Key (solo si la aplicación se encuentra en un servidor público); sin embargo, podrás usar la Google Maps Api  sin necesidad de la API Key, siempre que ejecutes localmente (localhost).
/**** Codigo fuente GoogleMapsExample.java *****/
public class GoogleMapsExample implements EntryPoint {

 public void onModuleLoad() {
  /*
   * En el primer parametro se debe de colocar
   * el Api Key en caso sea necesario  
  */
 Maps.loadMapsApi("", "2", false, new Runnable() {
  public void run() {
          buildUi();
        }
  });      
 }
 private void buildUi()
 {  
  final MapWidget map = new MapWidget();
 map.setWidth("500px");
  map.setHeight("500px");
 final LatLng coordenadas = LatLng.newInstance(-18.0376, -70.2506);
 //mostramos el mapa centrado con las coordenas (-18.0376, -70.2506)
 map.setCenter(coordenadas);
 //establecemos en nivel de zoom
 map.setZoomLevel(18);      
 RootPanel.get().add(map);    
 }
}   
¿Cómo añadir controles?
 Se pueden añadir muchos tipos de controles de zoom y navegación aquí la documentación.
private void buildUi()
 {
  final MapWidget map = new MapWidget();
  map.setWidth("500px");
  map.setHeight("500px");
  final LatLng coordenadas = LatLng.newInstance(-18.0376, -70.2506);
  //mostramos el mapa centrado con las coordenas (-18.0376, -70.2506)
  map.setCenter(coordenadas);
  //establecemos en nivel de zoom
  map.setZoomLevel(18);
  //añadimos control selector de tipo de mapa
  map.addControl(new MapTypeControl());
  //añadimos control de desplazmiento con zoom
  map.addControl(new LargeMapControl());
  //añadimos control escala de mapa
  map.addControl(new ScaleControl());
  RootPanel.get().add(map);        
 }
¿Cómo cambiar el tipo de mapa y añadir marcas?
 Podemos escoger el tipo de mapa que deseamos (satelital, hibrido, normal, etc.), además de poder añadir marcar a nuestro mapa.
private void buildUi()
 {
  final MapWidget map = new MapWidget();
  map.setWidth("500px");
  map.setHeight("500px");
  final LatLng coordenadas = LatLng.newInstance(-18.0376, -70.2506);
  //mostramos el mapa centrado con las coordenas (-18.0376, -70.2506)
  map.setCenter(coordenadas);
  //establecemos en nivel de zoom
  map.setZoomLevel(18);
  //añadimos control selector de tipo de mapa
  map.addControl(new MapTypeControl());
  //añadimos control de desplazamiento con zoom
  map.addControl(new LargeMapControl());
  //añadimos control escala de mapa
  map.addControl(new ScaleControl());
  //cambiamos a vista mapa satelital
  map.setCurrentMapType(MapType.getSatelliteMap());
  //creamos un marcador en la coordenadas (-18.0376, -70.2506)
  Marker mrk=new Marker(coordenadas);
  map.addOverlay(mrk);
  RootPanel.get().add(map);        
 }
¿Cómo lanzar una Ventana de Información (InfoWindow) al hacer un click sobre un Marcador?
 Al hacer un click sobre un Marcador se puede levantar una Ventana de Información que viene por defecto; sin embargo, esta Ventana de Información puede contener contenido html como Widgets.
private void buildUi()

 {

  final MapWidget map = new MapWidget();

  map.setWidth("500px");

  map.setHeight("500px");

  final LatLng coordenadas = LatLng.newInstance(-18.0376, -70.2506);

  //mostramos el mapa centrado con las coordenas (-18.0376, -70.2506)

  map.setCenter(coordenadas);

  //establecemos en nivel de zoom

  map.setZoomLevel(18);

  //añadimos control selector de tipo de mapa

  map.addControl(new MapTypeControl());

  //añadimos control de desplazamiento con zoom

  map.addControl(new LargeMapControl());

  //añadimos control escala de mapa

  map.addControl(new ScaleControl());

  //cambiamos a vista mapa satelital

  map.setCurrentMapType(MapType.getSatelliteMap());

  //creamos un marcador en la coordenadas (-18.0376, -70.2506)

  final Marker mrk=new Marker(coordenadas);

  map.addOverlay(mrk);  

  mrk.addMarkerClickHandler(new MarkerClickHandler(){

   @Override

   public void onClick(MarkerClickEvent event) {

    //Widget en InfoWindow Normal

    Image img=new Image();

    img.setUrl("http://lh6.ggpht.com/_oxEB1W000Zc/S5sCOsecjdI/AAAAAAAAAGg/_CDb-vUE7gs/s800/13%20DE%20SET.%20%20PLAZA%20ATMAT.JPG");

    img.setWidth("235px");

    img.setHeight("267px");

    //Widget en InfoWindow Maximizado

    HTML video= new HTML("<object width='180' height='160'><param name='movie' value='http://www.youtube.com/v/8qp_VSmV17I&hl=es_ES&fs=1&rel=0'></param><param name='allowFullScreen' value='true'></param><param name='allowscriptaccess' value='always'></param><embed src='http://www.youtube.com/v/8qp_VSmV17I&hl=es_ES&fs=1&rel=0' type='application/x-shockwave-flash' allowscriptaccess='always' allowfullscreen='false' width='180' height='160'></embed></object>");

    HTML album= new HTML("<embed type='application/x-shockwave-flash' src='http://picasaweb.google.com/s/c/bin/slideshow.swf' width='180' height='160' flashvars='host=picasaweb.google.com&hl=es&feat=flashalbum&RGB=0x000000&feed=http%3A%2F%2Fpicasaweb.google.com%2Fdata%2Ffeed%2Fapi%2Fuser%2FVictorCabreraZolla%2Falbumid%2F5447950544182068785%3Falt%3Drss%26kind%3Dphoto%26hl%3Des' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed>");    

    HorizontalPanel hp=new HorizontalPanel();

    hp.setSpacing(20);

    VerticalPanel vp=new VerticalPanel();

    vp.add(new HTML("video"));

    vp.add(video);

    vp.add(new HTML("diapositiva"));

    vp.add(album);

    hp.add(new HTML("<p style=\"text-align: justify;\">Este parque se construyo como un esfuerzo mancomunado del Sr. Alcalde  Jorge Jumanor  con los vecinos, haciendo realidad un sueño muchas veces  postergado por las anteriores autoridadede de Turno</p><p style=\"text-align: justify;\">La Obra se empezo  a contruir a inicios del año 2009 culminandose satisfactoriamente a  mediados del  2009 en el aniversario del Distrito Gregorio  Albarracion  Lanchipa</p>"));

    hp.add(vp);

    //creamos la Ventana de Informacion

    InfoWindowContent info=new InfoWindowContent(img);    

    info.setMaxTitle("Parque Perez Gamboa");

    info.setMaxContent(hp);

    map.getInfoWindow().open(mrk.getLatLng(),info);

   }

  }); 

  RootPanel.get().add(map);        

 } 
 En en siguiente video se muestra la ejecución del ejemplo:

sábado, junio 19, 2010

Cómo integrar SmartGWT con PHP usando DataSource?

SmartGwt no es otro tradicional framework Ajax que solo presenta y muestra datos via XML/Json u otro mecanismo (de estos hay bastantes!!!).  SmartGwt fue concebido para la administración del estado del lado del cliente y la propagación de cambios en el servidor. Por ejemplo, cuando tenemos varias grillas mostrando datos de una tabla y hemos añadido un registro por medio de un formulario, en ese instante deben de actualizarse las grillas automáticamente. Lo anterior se consigue con un mecanismo denominado databinding, lo cual significa que todas las grillas(widgets) se han enlazado al DataSource. Todas las operaciones CRUD se reflejaran automáticamente a todos los widgets enlazados.
A continuación implementaremos un ejemplo bastante básico de como SmartGwt se integra con PHP:

/*
* Codigo fuente de DataSourceCountry.java
*/
public class DataSourceCountry extends RestDataSource{

 private static DataSourceCountry instance = null;    
 
 public static DataSourceCountry getInstance() {  
       
     if (instance == null) {  
            
            instance = new DataSourceCountry();
            
        }  
        return instance;  
    }//fin de funcion
 static void AddData(Record record)
    {
     instance.addData(record);   
    }//fin de funcion 
    static void RemoveData(Record record)
    {
     instance.removeData(record);     
    }//fin de funcion
//public DataSourceCountry() Corregido por el amigo anonimo
    private DataSourceCountry()
    {
      DataSourceIntegerField id = new DataSourceIntegerField("id", "CATEGORIA ID"); 
   id.setPrimaryKey(true);  
   
   DataSourceTextField idcategoria = new DataSourceTextField("idcategoria", "PERTENECE A");  
   idcategoria.setForeignKey("id");  
   idcategoria.setRootValue("");  
 
   DataSourceTextField descripcion = new DataSourceTextField("descripcion", "DESCRIPCION");   
   DataSourceTextField categoria = new DataSourceTextField("categoria", "CATEGORIA");

   this.setFields(id,idcategoria,descripcion,categoria);  
   
   OperationBinding fetch = new OperationBinding();
   fetch.setOperationType(DSOperationType.FETCH);
   fetch.setDataProtocol(DSProtocol.POSTPARAMS);
   
   OperationBinding add = new OperationBinding();
   add.setOperationType(DSOperationType.ADD);
   add.setDataProtocol(DSProtocol.POSTPARAMS);
           
   OperationBinding remove = new OperationBinding();
   remove.setOperationType(DSOperationType.REMOVE);
   remove.setDataProtocol(DSProtocol.POSTPARAMS);
            
   this.setOperationBindings(fetch,add,remove);
   this.setDataFormat(DSDataFormat.JSON); 
  
   this.setFetchDataURL("fetch.php");  //integracion con PHP
   this.setAddDataURL("add.php");      //integracion con PHP
   this.setRemoveDataURL("remove.php");//integracion con PHP
    }
}
<?php
/*
* Codigo fuente de fetch.php
*/
$data=array();
$data[0]['id']=1;
$data[0]['descripcion']='descripcin plazas';
$data[0]['categoria']='plazas';
$data[0]['idcategoria']='';

$data[1]['id']=2;
$data[1]['descripcion']='descripcin comedores';
$data[1]['categoria']='comedores';
$data[1]['idcategoria']='';

$mensaje=array();
$mensaje['response']['status']=0;
$mensaje['response']['data']=$data;

echo json_encode($mensaje);
?>
En el archivo "remove.php" podemos notar que al remover un registro el DataSource envía el "id" del registro a eliminar, entonces el Servidor debe de responder con el "id" y un "status=0".
<?php
/*
* Codigo fuente de remove.php
*/
$data=array();
$data[0]['id']=$_POST['id'];

$mensaje=array();
$mensaje['response']['status']=0;
$mensaje['response']['data']=$data;

echo json_encode($mensaje);
?>
En el archivo "add.php" el DataSource envía el campo "descripción" y "categoria" enseguida el Servidor le devuelve los campos pero aumentando los campos "id" y "idcategoria".
<?php
/*
* Codigo fuente de add.php
*/
$data=array();
$data[0]['id']=3;
$data[0]['descripcion']=$_POST['descripcion'];
$data[0]['categoria']=$_POST['categoria'];
$data[0]['idcategoria']='';

$mensaje=array();
$mensaje['response']['status']=0;
$mensaje['response']['data']=$data;

echo json_encode($mensaje);
?>
Explicare un poco el archivo "Probandatasource.java". En la linea 21,37,41 realizamos el databinding con el DataSource con los Widgets TreeGrid,ListGrid y SelectItem respectivamente. En la linea 50 creamos un registro y lo enviamos al DataSource (al pulsar el botón añadir). En la linea 65 capturamos el "id" del registro seleccionado y lo enviamos al DataSource(al pulsar el botón eliminar)
/*
* Codigo fuente de Probandodatasource.java
*/
public class Probandodatasource implements EntryPoint {

 public void onModuleLoad() {
  final TreeGrid  countryGrid = new TreeGrid ();
        countryGrid.setCanFreezeFields(true);         
        countryGrid.setWidth("100%");  
        countryGrid.setHeight("100%");  
        countryGrid.setShowAllRecords(true);
        countryGrid.setLoadDataOnDemand(false);
       
        TreeGridField  descripcion = new TreeGridField ("descripcion", "Descripcion", 200);  
        TreeGridField  categoria = new TreeGridField ("categoria", "Categoria",200);  
  
        countryGrid.setFields(categoria, descripcion);  
        countryGrid.setCanResizeFields(true); 
        countryGrid.setAutoFetchData(true);

        countryGrid.setDataSource(DataSourceCountry.getInstance());
         
        final ListGrid  countryGridList = new ListGrid ();
        countryGridList.setCanFreezeFields(true);         
        countryGridList.setWidth("100%");  
        countryGridList.setHeight("100%");  
        countryGridList.setShowAllRecords(true);
        //countryGridList.setLoadDataOnDemand(false);
       
        ListGridField  descripcionList = new ListGridField ("descripcion", "Descripcion", 200);  
        ListGridField  categoriaList = new ListGridField ("categoria", "Categoria",200);  
  
        countryGridList.setFields(categoriaList, descripcionList);  
        countryGridList.setCanResizeFields(true); 
        countryGridList.setAutoFetchData(true);

        countryGridList.setDataSource(DataSourceCountry.getInstance());
        
        final SelectItem combobox = new SelectItem("ComboBox");  
    combobox.setWidth(240);  
    combobox.setOptionDataSource(DataSourceCountry.getInstance());  
    combobox.setDisplayField("categoria");  
    combobox.setPickListWidth(450);  
    combobox.setPickListFields(categoriaList, descripcionList); 
        
 
        IButton btnAnadir=new IButton("Añadir");
        btnAnadir.addClickHandler(new ClickHandler(){

   @Override
   public void onClick(ClickEvent event) {
    ListGridRecord rec = new ListGridRecord();    
    rec.setAttribute("idcategoria","");                          
                                rec.setAttribute("descripcion","descripcion de jardines");  
                                rec.setAttribute("categoria","jardines");  
    
    DataSourceCountry.AddData(rec);
   }
         
        });
        
        IButton btnRemove=new IButton("Remover");
        btnRemove.addClickHandler(new ClickHandler(){

   @Override
   public void onClick(ClickEvent event) {
    ListGridRecord id=countryGrid.getSelectedRecord();
    
    DataSourceCountry.RemoveData(id);
    }
         
        });
        
        VLayout vl=new VLayout();
        vl.setWidth100();
        vl.setHeight100();
        vl.addMember(countryGrid);
        vl.addMember(countryGridList);
        
        DynamicForm df=new DynamicForm();
        df.setItems(combobox);
        vl.addMember(df);
        
        vl.addMember(btnAnadir);
        vl.addMember(btnRemove);
        vl.draw();
        
 }
}
La implementación de este pequeñísimo ejemplo lo pueden ver en el video, cabe mencionar que copio y pego el código fuente de este blog a Eclipse; tal que, cualquiera con algo de entusiasmo y ganas lo pueda ejecutar.





Nota: Tengo la terrible costumbre de enfocarme en el funcionamiento, en lo próximos posts tratare de hacer ejemplos mucho mas estéticos!