InteriorPoint.java
/*
* Copyright (c) 2016 Martin Davis.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* and Eclipse Distribution License v. 1.0 which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v20.html
* and the Eclipse Distribution License is available at
*
* http://www.eclipse.org/org/documents/edl-v10.php.
*/
package org.locationtech.jts.algorithm;
import org.locationtech.jts.algorithm.construct.LargestEmptyCircle;
import org.locationtech.jts.algorithm.construct.MaximumInscribedCircle;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.GeometryCollection;
import org.locationtech.jts.geom.GeometryFilter;
/**
* Computes an interior point of a <code>{@link Geometry}</code>.
* An interior point is guaranteed to lie in the interior of the Geometry,
* if it possible to calculate such a point exactly.
* Otherwise, the point may lie on the boundary of the geometry.
* For collections the interior point is computed for the collection of
* non-empty elements of highest dimension.
* The interior point of an empty geometry is <code>null</code>.
*
* <h2>Algorithm</h2>
* The point is chosen to be "close to the center" of the geometry.
* The location depends on the dimension of the input:
*
* <ul>
* <li><b>Dimension 2</b> - the interior point is constructed in the middle of the longest interior segment
* of a line bisecting the area.
*
* <li><b>Dimension 1</b> - the interior point is the interior or boundary vertex closest to the centroid.
* <li><b>Dimension 0</b> - the point is the point closest to the centroid.
* </ul>
*
* @see Centroid
* @see MaximumInscribedCircle
* @see LargestEmptyCircle
*/
public class InteriorPoint {
/**
* Computes a location of an interior point in a {@link Geometry}.
* Handles all geometry types.
*
* @param geom a geometry in which to find an interior point
* @return the location of an interior point,
* or <code>null</code> if the input is empty
*/
public static Coordinate getInteriorPoint(Geometry geom) {
if (geom.isEmpty())
return null;
Coordinate interiorPt = null;
int dim = dimensionNonEmpty(geom);
// this should not happen, but just in case...
if (dim < 0) {
return null;
}
if (dim == 0) {
interiorPt = InteriorPointPoint.getInteriorPoint(geom);
}
else if (dim == 1) {
interiorPt = InteriorPointLine.getInteriorPoint(geom);
}
else {
interiorPt = InteriorPointArea.getInteriorPoint(geom);
}
return interiorPt;
}
private static int dimensionNonEmpty(Geometry geom) {
DimensionNonEmptyFilter dimFilter = new DimensionNonEmptyFilter();
geom.apply(dimFilter);
return dimFilter.getDimension();
}
private static class DimensionNonEmptyFilter implements GeometryFilter
{
private int dim = -1;
public int getDimension() {
return dim;
}
public void filter(Geometry elem) {
if (elem instanceof GeometryCollection)
return;
if (! elem.isEmpty()) {
int elemDim = elem.getDimension();
if (elemDim > dim) dim = elemDim;
}
}
}
}