package org.geotools.tutorial.function; import java.util.List; import org.geotools.filter.capability.FunctionNameImpl; import org.geotools.util.Converters; import org.opengis.filter.capability.FunctionName; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.ExpressionVisitor; import org.opengis.filter.expression.Function; import org.opengis.filter.expression.Literal; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.linearref.LinearLocation; import com.vividsolutions.jts.linearref.LocationIndexedLine; /** * Quick function that illustrates snapping to a line. * * @author jody */ public class SnapFunction implements Function { static FunctionName NAME = new FunctionNameImpl("snap", "point", "line"); private final List<Expression> parameters; private final Literal fallback; public SnapFunction(List<Expression> parameters, Literal fallback) { if (parameters == null) { throw new NullPointerException("parameters required"); } if (parameters.size() != 2) { throw new IllegalArgumentException( "snap( point, line) requires two parameters only"); } this.parameters = parameters; this.fallback = fallback; } public Object evaluate(Object object) { return evaluate(object, Point.class); } public <T> T evaluate(Object object, Class<T> context) { Expression pointExpression = parameters.get(0); Point point = pointExpression.evaluate(object, Point.class); Expression lineExpression = parameters.get(1); Geometry line = lineExpression.evaluate(object, Geometry.class); LocationIndexedLine index = new LocationIndexedLine(line); LinearLocation location = index.project(point.getCoordinate()); Coordinate snap = index.extractPoint(location); Point pt = point.getFactory().createPoint(snap); return Converters.convert(pt, context); // convert to requested format } public Object accept(ExpressionVisitor visitor, Object extraData) { return visitor.visit(this, extraData); } public String getName() { return NAME.getName(); } public FunctionName getFunctionName() { return NAME; } public List<Expression> getParameters() { return parameters; } public Literal getFallbackValue() { return fallback; } }