Here is a patch for DuplicatingFilterVisitor you can try if you like ....

public Object visit(Function expression, Object extraData) {
List old = expression.getParameters();
Expression[] args = new Expression[old.size()];
int i = 0;
for (Iterator iter = old.iterator(); iter.hasNext(); i++) {
Expression exp = (Expression) iter.next();
args[i]= visit(exp, extraData);
}
FilterFactory2 factory = getFactory(extraData);
try {
Function copy = factory.function(expression.getName(), args);
return copy;
}
catch (RuntimeException eek ){
LOGGER.warning("Unable to duplicate "+expression.getName()+" did you register 
it with META_INF/services? "+eek);
if( args.length == 0 ){
// this function is probably a volatile hack of some sort from 2.6 code
// since no arguments are harmed we can get away with ....
return expression;
}
throw eek;
}
}


-- 
Jody Garnett


On Tuesday, 5 July 2011 at 9:14 PM, Jody Garnett wrote:

> So got a chance to review your code; the tutorial where you register your 
> function is actually what you need; in your code it looks like you are trying 
> to cheat the system a bit ... ie so the function is not purely functional - 
> but is in part configured by an object you passed in. Indeed the object you 
> passed in looked almost exactly like the function interface so I am not sure 
> what you are up to...
> 
> public static class FunctionWrapper extends FunctionExpressionImpl {
> private ISimpleFeatureFilter simpleFeatureFilter;
> 
> public FunctionWrapper(ISimpleFeatureFilter simpleFeatureFilter) {
> super(simpleFeatureFilter.getName());
> this.simpleFeatureFilter = simpleFeatureFilter;
> }
> 
> @Override
> public int getArgCount() {
> return 0;
> }
> 
> @Override
> public Object evaluate(Object feature) {
> return simpleFeatureFilter.evaluate((SimpleFeature)feature);
> }
> }
> 
> public interface ISimpleFeatureFilter {
> public String getName();
> public boolean evaluate(SimpleFeature feature);
> }
> 
> You see how the argument count is 0? This is a sign it is trying to be a 
> function like random that is volatile in nature; that is the answer is not 
> strictly dependent on its inputs. With that in mind my original suggestion 
> still stands - we should have duplicate filter visitor *not* duplicate 
> volatile functions.
> 
> Also if you look in the tutorial you will see a base class AbstractFunction 
> which should allow the definition of a function with a minimum fuss and 
> bother if all you are looking to do is save a couple lines of coding with 
> your ISimpleFeatureFilter interface? I suspect that you have a user interface 
> or other class that implements ISimpleFeatureFilter and would like to go the 
> volatile function route ...
> 
> Finally you *can* use the Env function to solve this one ...
> 
> // this factory needs to be registered with geotools using META_INF/services 
> etc... as per the tutorial
> //
> public class FunctionWrapperFactory implements FunctionFactory { 
> private ArrayList<FunctionName> functionList;
> private static FunctionName WRAPPER = new 
> FunctionNameImpl("wrapper","simpleFeatureFilter");
> public synchronized List<FunctionName> getFunctionNames() {
> if( functionList == null ){
> functionList = new ArrayList<FunctionName>();
> functionList.add( WRAPPER );
> }
> return Collections.unmodifiableList( functionList );
> } 
> public Function function(String name, List<Expression> args, Literal 
> fallback) {
> if( "wrapper".equals(name)){
> return new AbstractFunction( WRAPPER, args, fallback ){
> public Geometry evaluate(Object object) {
> Geometry geom = eval(object, 0, Geometry.class );
> ISimpleFeatureFilter simpleFeatureFilter = eval( object,0, 
> ISimpleFeatureFilter );
> if( object instanceof SimpleFeatureFilter ){
>  return simpleFeatureFilter.evaualte( (SimpleFeature) object );
> }
> else {
>  return false; // not a simple feature so we cannot filter
> }
> }
> };
> }
> return null; // we do not implement that function
> }
> }
> 
> public interface ISimpleFeatureFilter {
> public String getName();
> public boolean evaluate(SimpleFeature feature);
> }
> 
> 
> In your calling code you have a choice....
> 
> static ISimpleFeatureFilter SIMPLE_FILTER = ....
> Filter filter = ff.equals( ff.function( "wrapper", ff.literal( SIMPLE_FILTER 
> ) ), ff.literal( Boolean.TRUE ) );
> 
> 1) Your ISimpleFeatureFilter is handed as an literal and thus can be copied 
> when Style needs to look at it
> 2) It does not (and your original does not) indicate to the rendering system 
> what attributes it wants the feature to have; so they may not be requested 
> (and the feature could be full of empty null values at runtime). Just so you 
> know ...
> 
> The other thing you could do is use an environment variable ... 
> http://docs.geotools.org/latest/javadocs/org/geotools/filter/function/EnvFunction.html
> 
> This is a good choice if you want want to change the value over time (perhaps 
> as your user interacts?).
> 
> EnvFunction.setGlobalValue("simple", simpleFeatureFilter );
> Filter filter = ff.equals( ff.function( "wrapper", ff.function( "env", 
> "simple" ) ), ff.literal( Boolean.TRUE ) );
> 
> .. later ...
> 
> EnvFunction.setGlobalValue("simple", simpleFeatureFilter2 );
> 
> Do you have a JIRA issue open on this topic? It would be good to record some 
> ideas and actually solve this; and it would be nice if you can tell me if the 
> above ideas work (perhaps I can get a blog post or a tutorial out of this 
> discussion). 
> 
> -- 
> Jody Garnett
> 
> 
> On Tuesday, 5 July 2011 at 8:12 PM, Jody Garnett wrote:
> 
> > There is hope :-) Please try the Env function; the javadocs should be 
> > enough to get you going. I think the idea is:
> > 1) construct your filter once using the Env function to refer to your 
> > selection (perhaps as "selection")
> > 2) when the user clicks on something set the "selection" to the appropriate 
> > value
> > 
> > -- 
> > Jody Garnett
> > 
> > 
> > On Tuesday, 5 July 2011 at 5:43 PM, LSA wrote:
> > 
> > > Any hope for me? My application is stuck to geotools 2.6.3, just because 
> > > of that.
> > > 
> > > I even ready for some crippled workaround solution.
> > > 
> > > Sergey
> > > 
> > > On 01.07.2011 10:40, Michael Bedward wrote:
> > > > Or are you talking about another example ?
> > > > Meanwhile, for Sergey's problem perhaps we could add a function
> > > > function to GeoTools: ie. a filter function that takes a user supplied
> > > > function, implementing some simple interface, as a parameter.
> > > > 
> > > > Michael
> > > > 
> > 
> 

------------------------------------------------------------------------------
All of the data generated in your IT infrastructure is seriously valuable.
Why? It contains a definitive record of application performance, security 
threats, fraudulent activity, and more. Splunk takes this data and makes 
sense of it. IT sense. And common sense.
http://p.sf.net/sfu/splunk-d2d-c2
_______________________________________________
Geotools-gt2-users mailing list
Geotools-gt2-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/geotools-gt2-users

Reply via email to