blob: b472d36c80d783ac2e6d0656e8f502d4c6f965ae [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sis.internal.feature.j2d;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.PathIterator;
import java.awt.geom.AffineTransform;
import org.apache.sis.internal.feature.AbstractGeometry;
import org.apache.sis.internal.referencing.j2d.IntervalRectangle;
/**
* A shape made of straight lines. This shape does not contain any Bézier curve.
* Consequently the flatness factor of path iterator can be ignored.
*
* @author Martin Desruisseaux (Geomatys)
* @version 1.1
* @since 1.1
* @module
*/
public abstract class FlatShape extends AbstractGeometry implements Shape {
/**
* Cached values of shape bounds.
*
* @see #getBounds2D()
*/
final IntervalRectangle bounds;
/**
* Creates a shape with the given bounds.
* The given argument is stored by reference; it is not cloned.
*
* @param bounds the shape bounds (not cloned).
*/
FlatShape(final IntervalRectangle bounds) {
this.bounds = bounds;
}
/**
* Creates a shape with bounds initialized to minimum and maximum coordinates of given array.
* The {@code coordinates} array shall not be empty.
*
* @param coordinates the coordinate values as (x,y) tuples.
* @param size number of valid value in {@code coordinates} array.
*/
FlatShape(final double[] coordinates, final int size) {
double xmax, ymax;
double xmin = xmax = coordinates[0];
double ymin = ymax = coordinates[1];
for (int i=2; i<size;) {
final double x = coordinates[i++];
final double y = coordinates[i++];
if (x < xmin) xmin = x;
if (x > xmax) xmax = x;
if (y < ymin) ymin = y;
if (y > ymax) ymax = y;
}
bounds = new IntervalRectangle(xmin, ymin, xmax, ymax);
}
/**
* Returns an integer rectangle that completely encloses the shape.
* There is no guarantee that the rectangle is the smallest bounding box that encloses the shape.
*/
@Override
public final Rectangle getBounds() {
return bounds.getBounds();
}
/**
* Returns a rectangle that completely encloses the shape.
* There is no guarantee that the rectangle is the smallest bounding box that encloses the shape.
*/
@Override
public final Rectangle2D getBounds2D() {
return bounds.getBounds2D();
}
/**
* Tests if the specified point is inside the boundary of the shape.
* This method delegates to {@link #contains(double, double)}.
*/
@Override
public final boolean contains(final Point2D p) {
return contains(p.getX(), p.getY());
}
/**
* Returns an iterator for the shape outline geometry. The flatness factor is ignored on the assumption
* that this shape does not contain any Bézier curve, as stipulated in {@code FlatShape} class contract.
*
* @param at an optional transform to apply on coordinate values.
* @param flatness ignored.
* @return an iterator for the shape outline geometry.
*/
@Override
public final PathIterator getPathIterator(final AffineTransform at, final double flatness) {
return getPathIterator(at);
}
/**
* Returns a potentially smaller shape containing all polylines that intersect the given area of interest.
* This method performs only a quick check based on bounds intersections. It does not test individual points.
* The returned shape may still have many points outside the given bounds.
*
* @param areaOfInterest the area of interest. Edges are considered exclusive.
* @return a potentially smaller shape, or {@code null} if this shape is fully outside the AOI.
*/
public FlatShape fastClip(final Rectangle2D areaOfInterest) {
return bounds.intersects(areaOfInterest) ? this : null;
}
}