martes, 29 de mayo de 2012

Tiempo en C++

Para medir el tiempo que pasa entre dos eventos (por ejemplo para realizar test de rendimiento) tan solo hay que importar la librería time.h y utilizar la función clock() que devuelve el ciclo de reloj de la CPU. A continuación un ejemplo de su uso:

#include <time.h>
#inculde <iostream>


// Variables para almacenar instantes
double tstart, tstop, ttime;

// .... aqui cabecera función/metodo etc.

// Tiempo inicial
tstart = (double)clock()/CLOCKS_PER_SEC;


// Aquí operaciones test rendimiento.

// Tiempo final
tstop = (double)clock()/CLOCKS_PER_SEC;
ttime= tstop-tstart; //Tiempo entre inicio y final

std::cout << "La operación ha llevado " << ttime << " segundos" << std::endl;

lunes, 21 de mayo de 2012

Lectura de archivos shapefile con GeoTools



GeoTools que es una biblioteca SIG de código libre que permite desarrollar soluciones adaptadas a los estándares proporcionando una implementación de las especificaciones del Open Geospatial Consortium (OGC) según van apareciendo. Es decir, que no solo permite la lectura archivos Shapefile sino que dispone de otras muchas funcionalidades entre las que destacan:
  • Lectura y escritura de otros formatos como GeoTiff, GML,  Jpeg, Png, etc...
  • Acceso a servicios web de datos geoespaciales como WMS, WFS, etc...
  • Proporciona estructuras para trabajo con datos geoespaciales, 
  • Realización de operaciones sobre datos espaciales.
  • Manejo y cambio entre sistemas de coordenadas.
  • Renderizado de datos.
  • Creación de interfaces de usuario.
Requisitos y configuración

Para poder trabajar con GeoTools tan solo debemos bajarnos la ultima versión (a día de hoy 2.7.4) y configurar nuestro IDE favorito importando las librerías que necesitemos que en nuestro caso será gt-shapefile-2.7.4.jar.

Código

En primer lugar deberemos realizar los siguientes imports que incluyen tanto las clases necesarias para cargar los shapefiles como para definir la geometría leída y los datos:

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.FeatureSource;
import org.geotools.feature.FeatureCollection;
import org.geotools.feature.FeatureIterator;
import org.opengis.feature.Feature;

import com.vividsolutions.jts.geom.GeometryCollection;



Y ya podemos pasar a realizar la apertura del fichero que en nuestro caso sera un fichero de polígonos (los shapefiles pueden ser de puntos, polilíneas o poligonos). Por tanto a la hora de trabajar con un shapefile tenemos que tener en cuenta su geometría y ademas como contiene datos en forma de cadena (es decir string) debemos tener en cuenta tamien su codificación. Así para abrir un fichero en que esta en utf-8 debemos escribir:

  // Definición del fichero al shapefile (es decir el que tiene la extensión .shp) de entre los que forman el shapefile (ver wikipedia para mas info).
 File file = new File("buildings.shp");
 Map connect = new HashMap();
  // Se establecen los parametros para abrir el fichero.
 connect.put("url", file.toURL());
 connect.put("charset", "utf-8");
 // Se abre el shapefile como almacen de datos.
 DataStore dataStore = DataStoreFinder.getDataStore(connect);
 String[] typeNames = dataStore.getTypeNames();
 String typeName = typeNames[0];

 System.out.println("Reading content " + typeName);
 // Se cargan datos y geometria
 FeatureSource featureSource = dataStore.getFeatureSource(typeName);
 FeatureCollection collection = featureSource.getFeatures();
 FeatureIterator iterator = collection.features();
 // Se recorre cada uno de los registros y se escribe el contenido en este caso un campo llamado name (que es una de las columnas del shapfile leído
try {
 while (iterator.hasNext()) {
  Feature feature = iterator.next();
  if (!feature.getProperty("name").getValue().toString().isEmpty()) {
             
    System.out.println(String.valueOf(feature.getProperty("name").getValue()));    GeometryCollection geo = (GeometryCollection)  feature.getDefaultGeometryProperty().getValue();
            
     // Se lee cada punto del polígono y se escribe
     for (int nC=0; nC < geo.getCoordinates().length; nC++) {
        System.out.println("\t" + String.valueOf(geo.getCoordinates()[nC].x)+
                           ", " + String.valueOf(geo.getCoordinates()[nC].y));
     }
   }     
         
 }
} finally {
    iterator.close();
} catch (Throwable e) {}


miércoles, 2 de mayo de 2012

PROLOG en Java

PROLOG proveniente del francés PROgrammation en LOGique, es un lenguaje de programación lógico e interpretado, bastante conocido en el medio de investigación en Inteligencia Artificial.A diferencia de los lenguajes tradicionales su uso se basa en la definición de reglas y predicados que nos permitirán llegar a una determinada conclusión. Para más información sobre este lenguaje podéis bajaros este libro en el que a parte de las bases sobre el lenguaje encontrareis ejemplos, proyectos, etc. 

Antes de comenzar para poder trabajar en PROLOG desde Java vamos a utilizar la librería GNU Prolog for Java aunque también os recomiendo descargaros SWI-Prolog para probar los scripts que utilicéis y que también se puede linkar desde Java.

En primer lugar vamos a definir un sencillo script en PROLOG que determina si alguien es descendiente de otro alguien para lo que definimos los siguientes predicados:

% definiciones de padres
padre(tito, pepe).
padre(pepe, paco).
padre(pepe, ana).
% definiciones de madres
madre(maria, pepe).
madre(pepa, paco).
madre(pepa, lope).
madre(pepa, kique).

%Y es padre de alguien cuyo hijo es X
%o Y es madre de alguien cuyo hijo es X
es_descendiente(X, Y) :- padre(Y, _) , padre(_, X);
                         madre(Y, _) , madre(_, X).


Para probar este código en SWI-Prolog en primer lugar creamos el fichero desde cualquier editor de textos o desde el entorno escribiendo (acordaros de poner siempre .(punto) al final de cada linea/frase/predicado en Prolog):

?- edit(file('C:/tudir/tuprolog.pl')).

Lo completamos con el script de antes y para cargarlo y poder trabajar con las reglas que se definen tendremos que escribir:

? consult('C:/tudir/tuprolog.pl').

Y por ultimo para comprobar que funciona correctamente podemos probar con las siguientes consultas:

?- es_descendiente(paco, tito). %Paco es descendiente de Tito.
    true.
?- es_descendiente(tito, kique).
    false.
?- es_descendiente(X, tito). %Quien es descendiente de tito
X = pepe ;
X = paco ;
X = ana .

Ahora la idea es poder hacer uso de las características de PROLOG desde Java por lo que deberemos al igual que se ha hecho en SWI-Prolog en primer lugar cargar el fichero y después ejecutar las consultas que queramos verificar. Para ello en primer lugar necesitamos referenciar la librería e importar las siguientes clases:

import gnu.prolog.term.AtomTerm;
import gnu.prolog.term.CompoundTerm;
import gnu.prolog.term.Term;
import gnu.prolog.term.VariableTerm;
import gnu.prolog.vm.Environment;
import gnu.prolog.vm.Interpreter;
import gnu.prolog.vm.PrologCode;
import gnu.prolog.vm.PrologException;

Lo siguiente es inicilizar el interprete para lo que deberemos escribir el siguiente código:

    /**
     * Entorno que usara el interprete.
     */
    Environment env;
    /**
     * Interprete de PROLOG.
     */
    Interpreter interpreter;

    env = new Environment();
    // Cargamos el fichero en el entorno.
    env.ensureLoaded(AtomTerm.get("C:\\tudir\\tuprolog.pl"));
    // Obtenemos el interprete
    interpreter = env.createInterpreter();
    // Y lo inicializamos
    env.runInitialization(interpreter);

Y por ultimo realizar las consultas  :

    // Argumentos para la consulta en este caso constantes.
    Term[] args = { AtomTerm.get("paco"), AtomTerm.get("tito") };
    // Construimos la consulta Paco es desdenciente de Tito?
    CompoundTerm goalTerm =
        new CompoundTerm(AtomTerm.get("es_descendiente"), args);

       
    try {
        if (interpreter.runOnce(goalTerm) == 
            PrologCode.SUCCESS)
        {               
            System.out.println("Pepe es descendiente de Tito.");
        } else {
            System.out.println("Pepe NO es descendiente de Tito.");
        }
    } catch (PrologException e) {
        System.out.println("Error." + e.getMessage());           
   
    // Fin. 
    env.closeStreams();       



Para más información podéis consultar la API de la librería o el ejemplo que viene con ella donde se realiza lo mismo pero con variables y mostrando las respuestas obtenidas.