/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2008 - 2010, Geomatys * * 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.geotoolkit.display2d.primitive.jts; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.LinearRing; import java.awt.Rectangle; import java.awt.Shape; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.geom.PathIterator; import java.awt.geom.Point2D; import java.awt.geom.Rectangle2D; import java.util.logging.Level; import org.apache.sis.util.logging.Logging; /** * A thin wrapper that adapts a JTS geometry to the Shape interface so that the geometry can be used * by java2d without coordinate cloning. * * @author Johann Sorel (Puzzle-GIS) * @version 2.9 * @module */ public abstract class AbstractJTSGeometryJ2D<T extends Geometry> implements Shape, Cloneable { /** The wrapped JTS geometry */ protected T geometry; /** An additional AffineTransform */ protected final AffineTransform transform; public AbstractJTSGeometryJ2D(final T geom) { this(geom, JTSGeometryIterator.IDENTITY); } /** * Creates a new GeometryJ2D object. * * @param geom - the wrapped geometry */ public AbstractJTSGeometryJ2D(final T geom, final AffineTransform trs) { this.geometry = geom; this.transform = trs; } /** * Sets the geometry contained in this lite shape. Convenient to reuse this * object instead of creating it again and again during rendering * * @param g */ public void setGeometry(final T g) { this.geometry = g; } /** * @return the current wrapped geometry */ public T getGeometry() { return geometry; } protected AffineTransform getInverse(){ try { return transform.createInverse(); } catch (NoninvertibleTransformException ex) { Logging.getLogger("org.geotoolkit.display2d.primitive.jts").log(Level.WARNING, ex.getMessage(), ex); return null; } } /** * {@inheritDoc } */ @Override public boolean contains(final Rectangle2D r) { return contains(r.getMinX(),r.getMinY(),r.getWidth(),r.getHeight()); } /** * {@inheritDoc } */ @Override public boolean contains(final Point2D p) { final AffineTransform inverse = getInverse(); inverse.transform(p, p); final Coordinate coord = new Coordinate(p.getX(), p.getY()); final Geometry point = geometry.getFactory().createPoint(coord); return geometry.contains(point); } /** * {@inheritDoc } */ @Override public boolean contains(final double x, final double y) { final Point2D p = new Point2D.Double(x, y); return contains(p); } /** * {@inheritDoc } */ @Override public boolean contains(final double x, final double y, final double w, final double h) { Geometry rect = createRectangle(x, y, w, h); return geometry.contains(rect); } /** * {@inheritDoc } */ @Override public Rectangle getBounds() { return getBounds2D().getBounds(); } /** * {@inheritDoc } */ @Override public Rectangle2D getBounds2D() { if(geometry == null) return null; final Envelope env = geometry.getEnvelopeInternal(); final Point2D p1 = new Point2D.Double(env.getMinX(), env.getMinY()); transform.transform(p1, p1); final Point2D p2 = new Point2D.Double(env.getMaxX(), env.getMaxY()); transform.transform(p2, p2); final Rectangle2D rect = new Rectangle2D.Double(p1.getX(), p1.getY(), 0, 0); rect.add(p2); return rect; } /** * {@inheritDoc } */ @Override public PathIterator getPathIterator(final AffineTransform at, final double flatness) { return getPathIterator(at); } /** * {@inheritDoc } */ @Override public boolean intersects(final Rectangle2D r) { final Geometry rect = createRectangle( r.getMinX(), r.getMinY(), r.getWidth(), r.getHeight()); return geometry.intersects(rect); } /** * {@inheritDoc } */ @Override public boolean intersects(final double x, final double y, final double w, final double h) { Geometry rect = createRectangle(x, y, w, h); return geometry.intersects(rect); } /** * Creates a jts Geometry object representing a rectangle with the given * parameters * * @param x left coordinate * @param y bottom coordinate * @param w width * @param h height * * @return a rectangle with the specified position and size */ private Geometry createRectangle(final double x, final double y, final double w, final double h) { final AffineTransform inverse = getInverse(); final Point2D p1 = new Point2D.Double(x, y); inverse.transform(p1, p1); final Point2D p2 = new Point2D.Double(x+w, y+h); inverse.transform(p2, p2); final Coordinate[] coords = { new Coordinate(p1.getX(), p1.getY()), new Coordinate(p1.getX(), p2.getY()), new Coordinate(p2.getX(), p2.getY()), new Coordinate(p2.getX(), p1.getY()), new Coordinate(p1.getX(), p1.getY()) }; final LinearRing lr = geometry.getFactory().createLinearRing(coords); return geometry.getFactory().createPolygon(lr, null); } @Override public AbstractJTSGeometryJ2D clone() { return null; //TODO } }