001: /*
002: * Geotools2 - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002, Geotools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: *
016: */
017: package org.geotools.renderer.shape;
018:
019: import java.util.Stack;
020:
021: import org.geotools.filter.visitor.AbstractFilterVisitor;
022:
023: import com.vividsolutions.jts.geom.Envelope;
024: import com.vividsolutions.jts.geom.Geometry;
025: import com.vividsolutions.jts.geom.GeometryFactory;
026:
027: /**
028: * Visits a filter and extracts the minimum bounds that the filter requires.
029: *
030: * @author jones
031: */
032: public class BoundsExtractor extends AbstractFilterVisitor {
033: private Stack/*<Envelope>*/envelopeStack = new Stack/*<Envelope>*/();
034:
035: private final Envelope original;
036:
037: private Envelope notEnvelope;
038:
039: private final static GeometryFactory factory = new GeometryFactory();
040:
041: public BoundsExtractor(Envelope bbox) {
042: original = bbox;
043: }
044:
045: public BoundsExtractor(int minx, int maxx, int miny, int maxy) {
046: this (new Envelope(minx, maxx, miny, maxy));
047: }
048:
049: /**
050: * @return the intersecton of the new bbox and the original
051: */
052: public Envelope getIntersection() {
053: Envelope bbox = null;
054: if (!envelopeStack.isEmpty())
055: bbox = (Envelope) envelopeStack.peek();
056: if (original == null) {
057: return bbox == null ? new Envelope() : bbox;
058: }
059: if (bbox != null)
060: return bbox.intersection(original);
061: if (notEnvelope != null) {
062: return intersectionWithNotEnvelope(original);
063: }
064: return original;
065: }
066:
067: /**
068: * @return the intersecton of the new bbox and the original
069: */
070: public Envelope getFilterEnvelope() {
071: if (envelopeStack.isEmpty())
072: return new Envelope();
073: return (Envelope) envelopeStack.peek();
074: }
075:
076: public Envelope getNotEnvelope() {
077: return notEnvelope == null ? new Envelope() : notEnvelope;
078: }
079:
080: // /*
081: // * @see org.geotools.filter.FilterVisitor#visit(org.geotools.filter.LogicFilter)
082: // */
083: // public void visit(LogicFilter filter) {
084: //
085: // if (filter != null) {
086: // switch (filter.getFilterType()) {
087: // case FilterType.LOGIC_OR: {
088: // Iterator i = filter.getFilterIterator();
089: // while (i.hasNext()) {
090: // Filter tmp = (Filter) i.next();
091: // tmp.accept(this);
092: // }
093: // Envelope bbox=new Envelope();
094: // while( !envelopeStack.isEmpty() ){
095: // Envelope env = (Envelope) envelopeStack.pop();
096: // bbox.expandToInclude(env);
097: // }
098: // if( notEnvelope!=null ){
099: // if( bbox.contains(notEnvelope) ){
100: // // or contains all of notEnvelope so notEnvelope is meaningless
101: // notEnvelope=null;
102: // }else{
103: // // lets err on the side of caution and we can safely ignore the or... This will
104: // // be a little big but that's ok.
105: // bbox=new Envelope();
106: // }
107: // }
108: //
109: // if( !bbox.isNull() )
110: // envelopeStack.push(bbox);
111: // break;
112: // }
113: // case FilterType.LOGIC_AND: {
114: // Iterator i = filter.getFilterIterator();
115: // while (i.hasNext()) {
116: // Filter tmp = (Filter) i.next();
117: // tmp.accept(this);
118: // }
119: // if( !envelopeStack.isEmpty() ){
120: // Envelope bbox = null;
121: // while( !envelopeStack.isEmpty() ){
122: // Envelope env = (Envelope) envelopeStack.pop();
123: // if( bbox==null ){
124: // bbox=env;
125: // }else{
126: // bbox=bbox.intersection(env);
127: // }
128: // }
129: // if( notEnvelope!=null && bbox!=null){
130: // if( notEnvelope.contains(bbox) ){
131: // // this mean that nothing valid since we are ANDING
132: // // and area with an area that is guaranteed to be empty
133: // // Erring on the side of caution for now
134: // notEnvelope=bbox;
135: // bbox=null;
136: // }else{
137: // bbox = intersectionWithNotEnvelope(bbox);
138: // notEnvelope=null;
139: // }
140: // }
141: // if( bbox!=null && !bbox.isNull() )
142: // envelopeStack.push(bbox);
143: // }
144: //
145: // break;
146: // }
147: // case FilterType.LOGIC_NOT:
148: // Iterator i = filter.getFilterIterator();
149: // Filter tmp = (Filter) i.next();
150: // tmp.accept(this);
151: // if( !envelopeStack.isEmpty() ){
152: // notEnvelope=(Envelope) envelopeStack.pop();
153: // assert envelopeStack.isEmpty();
154: // }else if( notEnvelope!=null || !notEnvelope.isNull()){
155: // envelopeStack.push(notEnvelope);
156: // notEnvelope=null;
157: // }
158: // default:
159: // break;
160: // }
161: //
162: // }
163: // }
164: //
165: private Envelope intersectionWithNotEnvelope(Envelope bbox) {
166: Geometry notGeom = factory.toGeometry(notEnvelope);
167: Geometry andGeom = factory.toGeometry(bbox);
168:
169: Envelope envelopeInternal = andGeom.difference(notGeom)
170: .getEnvelopeInternal();
171: bbox = envelopeInternal;
172: return bbox;
173: }
174: //
175: // public void visit(LiteralExpression expression) {
176: // Object literal = expression.getLiteral();
177: // if (literal instanceof Geometry) {
178: // Geometry geom = (Geometry) literal;
179: // envelopeStack.push(geom.getEnvelopeInternal());
180: // }
181: // }
182: }
|