Created
November 13, 2010 22:20
-
-
Save jericks/675700 to your computer and use it in GitHub Desktop.
A GeoScript Function implementation in Groovy
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import geoscript.feature.Field | |
import org.geotools.factory.CommonFactoryFinder | |
import org.opengis.filter.expression.Function as GtFunction | |
import org.geotools.filter.FunctionImpl | |
import org.opengis.filter.expression.Expression | |
/** | |
* A GeoScript Function either wraps an existing GeoTools Function or | |
* can easily create a new Function by passing in a Closure. | |
* @author Jared Erickson | |
*/ | |
class Function extends FunctionImpl { | |
/** | |
* The GeoTools CommonFactoryFinder for finding GeoTools Functions | |
*/ | |
private static def ff = CommonFactoryFinder.getFilterFactory2(null) | |
/** | |
* The GeoTools Functions | |
*/ | |
private GtFunction function = null | |
/** | |
* The Groovy Closure | |
*/ | |
private Closure closure = null | |
/** | |
* Create a new Function by looking up an existing GeoTools Function by name | |
* and a List of parameters | |
* @param name The name of the existing Function | |
* @param parameters The List of parameters | |
*/ | |
Function(String name, List parameters) { | |
function = ff.function(name, convertParametersToExpressions(parameters).toArray() as Expression[]) | |
} | |
/** | |
* Create a new Function with a name, a List of parameters, and a Closure | |
* @param name The name of the new Function | |
* @param parameters The List of parameters | |
* @param closure The Closure | |
*/ | |
Function(String name, List parameters, Closure closure) { | |
setName(name) | |
setParameters(convertParametersToExpressions(parameters)) | |
this.closure = closure | |
} | |
/** | |
* Convert the List of parameters to a List of org.opengis.filter.expression.Expression's. | |
* All geoscript.feature.Fields are encoded as Properties and everything | |
* else if a Literal | |
* @param parameters The List of parameters | |
* @return A List of org.opengis.filter.expression.Expression's | |
*/ | |
private static List<Expression> convertParametersToExpressions(List parameters) { | |
parameters.collect{param -> | |
if (param instanceof Field) { | |
return ff.property(param.name) | |
} | |
else { | |
return ff.literal(param) | |
} | |
} | |
} | |
/** | |
* Evaluate the Function | |
* @param object The Object (may be null) | |
* @return An Object | |
*/ | |
def evaluate(Object object) { | |
if (function != null) { | |
// A GeoScript Layer == GeoTools FeatureCollection | |
if (object instanceof geoscript.layer.Layer) { | |
object = object.fs.features | |
} | |
return function.evaluate(object) | |
} | |
else { | |
// Unwrap Expression (Property => Field, Literal => .literal) | |
return closure(parameters, object) | |
} | |
} | |
/** | |
* Evaluate the Function | |
* @return An Object | |
*/ | |
def evaluate() { | |
evaluate(null) | |
} | |
/** | |
* A Groovyism that allows function() instead of function.evaluate() | |
* @return An Object | |
*/ | |
def call() { | |
evaluate() | |
} | |
/** | |
* A Groovyism that allows function(obj) instead of function.evaluate(obj) | |
* @param obj The parameter | |
* @return An Object | |
*/ | |
def call(Object obj) { | |
evaluate(obj) | |
} | |
/** | |
* The string presentation | |
* @return The name of the Function | |
*/ | |
String toString() { | |
name | |
} | |
} | |
// Create a Function from an existing Function | |
def shp = new geoscript.layer.Shapefile("states.shp") | |
def quantileFunction = new Function("Quantile", [new Field("PERSONS", "Double"), 5]) | |
def quantiles = quantileFunction.evaluate(shp) | |
println(quantiles.titles) | |
// Create a Function from an existing Function | |
def maxFunction = new Function("max", [2,4]) | |
println(maxFunction.evaluate()) | |
// Create a Function from an existing Function | |
def minFunction = new Function("min", [2,4]) | |
println(minFunction.evaluate()) | |
// Create a new Function using a Closure | |
def addFunction = new Function("add", [2,5], {params, obj -> | |
params[0].literal + params[1].literal | |
}) | |
println(addFunction.evaluate()) | |
println(addFunction()) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment