/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2008, 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.renderer.shape; import java.util.Stack; import org.geotools.filter.visitor.AbstractFilterVisitor; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; /** * Visits a filter and extracts the minimum bounds that the filter requires. * * @author jones * * * * @source $URL$ */ public class BoundsExtractor extends AbstractFilterVisitor{ private Stack/*<Envelope>*/ envelopeStack=new Stack/*<Envelope>*/(); private final Envelope original; private Envelope notEnvelope; private final static GeometryFactory factory=new GeometryFactory(); public BoundsExtractor(Envelope bbox) { original=bbox; } public BoundsExtractor(int minx, int maxx, int miny, int maxy) { this(new Envelope(minx, maxx, miny, maxy)); } /** * @return the intersecton of the new bbox and the original */ public Envelope getIntersection() { Envelope bbox=null; if( !envelopeStack.isEmpty()) bbox=(Envelope) envelopeStack.peek(); if( original==null ){ return bbox==null?new Envelope():bbox; } if( bbox!=null ) return bbox.intersection(original); if( notEnvelope!=null ){ return intersectionWithNotEnvelope(original); } return original; } /** * @return the intersecton of the new bbox and the original */ public Envelope getFilterEnvelope() { if( envelopeStack.isEmpty() ) return new Envelope(); return (Envelope) envelopeStack.peek(); } public Envelope getNotEnvelope() { return notEnvelope==null?new Envelope():notEnvelope; } // /* // * @see org.geotools.filter.FilterVisitor#visit(org.geotools.filter.LogicFilter) // */ // public void visit(LogicFilter filter) { // // if (filter != null) { // switch (filter.getFilterType()) { // case FilterType.LOGIC_OR: { // Iterator i = filter.getFilterIterator(); // while (i.hasNext()) { // Filter tmp = (Filter) i.next(); // tmp.accept(this); // } // Envelope bbox=new Envelope(); // while( !envelopeStack.isEmpty() ){ // Envelope env = (Envelope) envelopeStack.pop(); // bbox.expandToInclude(env); // } // if( notEnvelope!=null ){ // if( bbox.contains(notEnvelope) ){ // // or contains all of notEnvelope so notEnvelope is meaningless // notEnvelope=null; // }else{ // // lets err on the side of caution and we can safely ignore the or... This will // // be a little big but that's ok. // bbox=new Envelope(); // } // } // // if( !bbox.isNull() ) // envelopeStack.push(bbox); // break; // } // case FilterType.LOGIC_AND: { // Iterator i = filter.getFilterIterator(); // while (i.hasNext()) { // Filter tmp = (Filter) i.next(); // tmp.accept(this); // } // if( !envelopeStack.isEmpty() ){ // Envelope bbox = null; // while( !envelopeStack.isEmpty() ){ // Envelope env = (Envelope) envelopeStack.pop(); // if( bbox==null ){ // bbox=env; // }else{ // bbox=bbox.intersection(env); // } // } // if( notEnvelope!=null && bbox!=null){ // if( notEnvelope.contains(bbox) ){ // // this mean that nothing valid since we are ANDING // // and area with an area that is guaranteed to be empty // // Erring on the side of caution for now // notEnvelope=bbox; // bbox=null; // }else{ // bbox = intersectionWithNotEnvelope(bbox); // notEnvelope=null; // } // } // if( bbox!=null && !bbox.isNull() ) // envelopeStack.push(bbox); // } // // break; // } // case FilterType.LOGIC_NOT: // Iterator i = filter.getFilterIterator(); // Filter tmp = (Filter) i.next(); // tmp.accept(this); // if( !envelopeStack.isEmpty() ){ // notEnvelope=(Envelope) envelopeStack.pop(); // assert envelopeStack.isEmpty(); // }else if( notEnvelope!=null || !notEnvelope.isNull()){ // envelopeStack.push(notEnvelope); // notEnvelope=null; // } // default: // break; // } // // } // } // private Envelope intersectionWithNotEnvelope(Envelope bbox) { Geometry notGeom = factory.toGeometry(notEnvelope); Geometry andGeom = factory.toGeometry(bbox); Envelope envelopeInternal = andGeom.difference(notGeom).getEnvelopeInternal(); bbox = envelopeInternal; return bbox; } // // public void visit(LiteralExpression expression) { // Object literal = expression.getLiteral(); // if (literal instanceof Geometry) { // Geometry geom = (Geometry) literal; // envelopeStack.push(geom.getEnvelopeInternal()); // } // } }