/* * 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.filter.visitor; import org.geotools.geometry.jts.ReferencedEnvelope; import org.opengis.filter.expression.Expression; import org.opengis.filter.expression.Literal; import org.opengis.filter.spatial.BBOX; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; /** * Visit the BBOX filter elements and make sure they are valid. * <p> * Any BBOX filter using a literal geometry will be changed to be a literal envelope based on the * geometry internal envelope. If a max bounding box has been provided it will be used to clip this * request envelope. * <p> * * @author Jody * * @source $URL: http://svn.osgeo.org/geotools/trunk/modules/library/main/src/main/java/org/geotools/filter/visitor/FixBBOXFilterVisitor.java $ */ public class FixBBOXFilterVisitor extends DuplicatingFilterVisitor { // private static final Logger logger = Logging.getLogger("org.geotools.filter"); /** * Represents a hard limit; requests outside of this bound are assumed to be invalid for the WFS * resulting in an exception being thrown. */ ReferencedEnvelope maxbbox; /** * Visitor used to "clean up" any BBOX expressions. * * @param max Max bounding box used to clip any BBox expressions to ensure they are vaild */ public FixBBOXFilterVisitor(ReferencedEnvelope fsd) { maxbbox = fsd; } @SuppressWarnings("deprecation") @Override public Object visit(BBOX filter, Object extraData) { Envelope bbox = null; Expression leftGeometry = filter.getExpression1(); Expression rightGeometry = filter.getExpression2(); boolean clipped = false; Literal le = null; if (leftGeometry != null && leftGeometry instanceof Literal) { le = (Literal) leftGeometry; } else if (rightGeometry != null && rightGeometry instanceof Literal) { le = (Literal) rightGeometry; } if (le != null && le.getValue() != null && le.getValue() instanceof Geometry) { Geometry geometry = (Geometry) le.getValue(); bbox = geometry.getEnvelopeInternal(); } if (bbox == null) { // huh? no literal? Allow super class to sort it out ... return super.visit(filter, extraData); // allow super class to make a direct copy } double minx = bbox.getMinX(); double miny = bbox.getMinY(); double maxx = bbox.getMaxX(); double maxy = bbox.getMaxY(); if (maxbbox != null) { if (minx < maxbbox.getMinX()) { minx = maxbbox.getMinX(); clipped = true; } if (maxx > maxbbox.getMaxX()) { maxx = maxbbox.getMaxX(); clipped = true; } if (miny < maxbbox.getMinY()) { miny = maxbbox.getMinY(); clipped = true; } if (maxy > maxbbox.getMaxY()) { maxy = maxbbox.getMaxY(); clipped = true; } } if (clipped) { // the bbox was clipped! String propertyName = filter.getPropertyName(); String srs = filter.getSRS(); return getFactory(extraData).bbox(propertyName, minx, miny, maxx, maxy, srs); } else { return super.visit(filter, extraData); // allow super class to make a direct copy } } }