Invocación de operaciones
Este documento explica cómo invocar a una operación asociada a un tipo de geometría.
Para que una operación se pueda invocar antes que tenido que ser registrada. Una vez que se haya registrado, podremos ejecutar la operación sobre la propia geometría sólo con saber el nombre de la operación. Por ejemplo, para ejecutar la operación println hay que ejecutar el siguiente código (asumimos que existe una geometría de tipo punto en 2 dimensiones llamada point que ha sido creada previamente y que la operación se ha registrado sobre ese tipo de geometría).
Object obj = point.invokeOperation("println", null);
Las operaciones devolverán un objeto de tipo Object con el resultado de la operación. En la invocación del método invokeOperation aparece un segundo parámetro que no se ha utilizado en el ejemplo. Este argumento es de tipo GeometryOperationContext y no es más que un Map que contiene todos los parámetros de entrada que una operación puede recibir.
En el siguiente ejemplo se invoca a una operación llamada intersects que se ejecuta sobre dos geometrías. Para ello asumimos que existen dos Surface's en 2 dimensiones llamadas surface1 y surface2 que han sido creadas previamente:
GeometryOperationContext geomertyOperationContext = new GeometryOperationContext();
geometryOperationContext.setAttribute("geom2", surface2);
Boolean results = (Boolean)surface1.invokeOperation("intersects", geomertyOperationContext);
Para que este código funcione se ha tenido que suponer que la operación intersects se ejecuta en un "contexto" en el que existe una segunda geometría que se registra con el nombre "geom2". Esto es un poco incómodo de manejar, ya que implica que se deberían conocer todos los nombres de los objectos que el contexto de la operación utiliza para poder crear el contexto adecuado.
Para evitar esto, se pueden crear unas clases de contexto específicas para ejecutar una operación concreta. En el caso de intersects se puede crear una clase como la siguiente:
public class IntersectsGeometryOperationContext extends
GeometryOperationContext {
public IntersectsGeometryOperationContext(Geometry geom){
this.setGeom(geom);
}
public Geometry getGeom() {
return (Geometry)getAttribute("geom2");
}
public void setGeom(Geometry geom) {
setAttribute("geom2", geom);
}
}
De modo que ya no necesitamos saber el nombre de la propiedad del Map que almacena la segunda geometría. En el siguiente ejemplo se va a ejecutar el mismo código que en ejemplo anterior pero esta vez se va a utiliar el contexto específico para la operación:
IntersectsGeometryOperationContext intersectsContext = new GeometryOperationContext(surface2);
Boolean results = (Boolean)surface1.invokeOperation("intersects", intersectsContext);
No es necesario utilizar el Map que proporciona GeometryOperationContext. Se pueden crear atributos de clase para almacenar los parámetros del contexto y hacer una implementación personalizada.
Otra posible forma de ejecutar las operaciones es por código. Las operaciones tienen por convenio una variable estática de tipo integer que devuelve el código de la operación. Para ejecutar el código asociado a la operación intersercs ejecutamos el siguiente código (asumiendo que existe una clase IntersectsOperation):
IntersectsGeometryOperationContext intersectsContext = new GeometryOperationContext(surface2);
Boolean results = (Boolean)surface1.invokeOperation(Intersects.CODE, intersectsContext);
Los ejemplos que se han comentado hasta aquí sirven para poder ejecutar una operación para un tipo de geometría concreto. Pero hay que tener en cuenta que la hacer una invocación estamos pasando como parámetro un identificador de operación que utilizará la geometría para buscar la operación a ejecutar. En algunos casos en lo que existe un bucle dónde hay que ejecutar la misma operación, la ejecución de operaciones utilizando este mecanismo puede ser lenta, por lo que existe una forma de optimizar el acceso a las operaciones.
El GeometryManager tiene un método llamado getGeometryOperation que devuelve una operación dado un tipo y un subtipo de geometría. Si por ejemplo se quiere ejecutar la operación intersects en un bucle de Surface's en 2 dimensiones (suponemos que tenemos las surfaces en una variable de tipo List<Surface> llamada surfaces) sobre una surface conocida (suponemos que existe una variable de tipo surface2) se podría ejecutar el siguiente código:
GeometryOperation intersectsOperation = geometryManager.getGeometryOperation(Intersects.CODE, Geometry.TYPES.Point, Geometry.SUBTYPES.GEOM2D);
IntersectsGeometryOperationContext intersectsContext = new GeometryOperationContext(surface2);
for (int i=0 ; i<surfaces.size() ; i++){
intersectsOperation.invoke(surfaces.get(i), intersectsContext);
}