/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2014, Open Source Geospatial Foundation (OSGeo) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package org.geotools.styling.css.util; import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; import org.geotools.factory.CommonFactoryFinder; import org.geotools.filter.visitor.SimplifyingFilterVisitor; import org.geotools.styling.css.selector.Accept; import org.geotools.styling.css.selector.And; import org.geotools.styling.css.selector.Data; import org.geotools.styling.css.selector.Id; import org.geotools.styling.css.selector.Or; import org.geotools.styling.css.selector.PseudoClass; import org.geotools.styling.css.selector.Reject; import org.geotools.styling.css.selector.ScaleRange; import org.geotools.styling.css.selector.Selector; import org.geotools.styling.css.selector.SelectorVisitor; import org.geotools.styling.css.selector.TypeName; import org.opengis.feature.type.FeatureType; import org.opengis.filter.Filter; import org.opengis.filter.FilterFactory2; import org.opengis.filter.identity.FeatureId; import org.opengis.filter.identity.Identifier; /** * Turns a Selector into an OGC filter * * @author Andrea Aime - GeoSolutions * */ public class OgcFilterBuilder implements SelectorVisitor { public static OgcFilterBuilder INSTANCE = new OgcFilterBuilder(); static final FilterFactory2 FF = CommonFactoryFinder.getFilterFactory2(); @Override public Object visit(Accept accept) { return Filter.INCLUDE; } @Override public Object visit(Reject reject) { return Filter.EXCLUDE; } @Override public Object visit(Id id) { if (id.ids == null || id.ids.isEmpty()) { return Filter.INCLUDE; } Set<Identifier> identifiers = new LinkedHashSet<>(); for (String identifier : id.ids) { FeatureId featureId = FF.featureId(identifier); identifiers.add(featureId); } return FF.id(identifiers); } @Override public Object visit(Data data) { return data.filter; } @Override public Object visit(And and) { List<Filter> filters = new ArrayList<>(); for (Selector child : and.getChildren()) { Filter filter = (Filter) child.accept(this); if (filter == Filter.EXCLUDE) { return Filter.EXCLUDE; } else if (filter != Filter.INCLUDE) { filters.add(filter); } } if (filters.isEmpty()) { return Filter.INCLUDE; } else { return FF.and(filters); } } @Override public Object visit(Or or) { List<Filter> filters = new ArrayList<>(); for (Selector child : or.getChildren()) { Filter filter = (Filter) child.accept(this); if (filter == Filter.INCLUDE) { return Filter.INCLUDE; } else if (filter != Filter.EXCLUDE) { filters.add(filter); } } if (filters.isEmpty()) { return Filter.EXCLUDE; } else { return FF.or(filters); } } @Override public Object visit(TypeName typeName) { // ignore, it has been handled elsewhere return Filter.INCLUDE; } @Override public Object visit(ScaleRange scaleRange) { // ignore, it has been handled elsewhere return Filter.INCLUDE; } @Override public Object visit(PseudoClass pseudoClass) { // ignore, it has been handled elsewhere return Filter.INCLUDE; } public static Filter buildFilter(Selector selector, FeatureType targetFeatureType) { Filter filter = (Filter) selector.accept(INSTANCE); SimplifyingFilterVisitor simplifier = new UnboundSimplifyingFilterVisitor(); simplifier.setFeatureType(targetFeatureType); return (Filter) filter.accept(simplifier, null); } }