001: /*
002: * The JTS Topology Suite is a collection of Java classes that
003: * implement the fundamental operations required to validate a given
004: * geo-spatial data set to a known topological specification.
005: *
006: * Copyright (C) 2001 Vivid Solutions
007: *
008: * This library is free software; you can redistribute it and/or
009: * modify it under the terms of the GNU Lesser General Public
010: * License as published by the Free Software Foundation; either
011: * version 2.1 of the License, or (at your option) any later version.
012: *
013: * This library is distributed in the hope that it will be useful,
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
016: * Lesser General Public License for more details.
017: *
018: * You should have received a copy of the GNU Lesser General Public
019: * License along with this library; if not, write to the Free Software
020: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
021: *
022: * For more information, contact:
023: *
024: * Vivid Solutions
025: * Suite #1A
026: * 2328 Government Street
027: * Victoria BC V8T 5G5
028: * Canada
029: *
030: * (250)385-6040
031: * www.vividsolutions.com
032: */
033: package com.vividsolutions.jts.algorithm;
034:
035: import com.vividsolutions.jts.geom.*;
036:
037: /**
038: * Computes a point in the interior of an linear geometry.
039: * <h2>Algorithm</h2>
040: * <ul>
041: * <li>Find an interior vertex which is closest to
042: * the centroid of the linestring.
043: * <li>If there is no interior vertex, find the endpoint which is
044: * closest to the centroid.
045: * </ul>
046: *
047: * @version 1.7
048: */
049: public class InteriorPointLine {
050:
051: private Coordinate centroid;
052: private double minDistance = Double.MAX_VALUE;
053:
054: private Coordinate interiorPoint = null;
055:
056: public InteriorPointLine(Geometry g) {
057: centroid = g.getCentroid().getCoordinate();
058: addInterior(g);
059: if (interiorPoint == null)
060: addEndpoints(g);
061: }
062:
063: public Coordinate getInteriorPoint() {
064: return interiorPoint;
065: }
066:
067: /**
068: * Tests the interior vertices (if any)
069: * defined by a linear Geometry for the best inside point.
070: * If a Geometry is not of dimension 1 it is not tested.
071: * @param geom the geometry to add
072: */
073: private void addInterior(Geometry geom) {
074: if (geom instanceof LineString) {
075: addInterior(geom.getCoordinates());
076: } else if (geom instanceof GeometryCollection) {
077: GeometryCollection gc = (GeometryCollection) geom;
078: for (int i = 0; i < gc.getNumGeometries(); i++) {
079: addInterior(gc.getGeometryN(i));
080: }
081: }
082: }
083:
084: private void addInterior(Coordinate[] pts) {
085: for (int i = 1; i < pts.length - 1; i++) {
086: add(pts[i]);
087: }
088: }
089:
090: /**
091: * Tests the endpoint vertices
092: * defined by a linear Geometry for the best inside point.
093: * If a Geometry is not of dimension 1 it is not tested.
094: * @param geom the geometry to add
095: */
096: private void addEndpoints(Geometry geom) {
097: if (geom instanceof LineString) {
098: addEndpoints(geom.getCoordinates());
099: } else if (geom instanceof GeometryCollection) {
100: GeometryCollection gc = (GeometryCollection) geom;
101: for (int i = 0; i < gc.getNumGeometries(); i++) {
102: addEndpoints(gc.getGeometryN(i));
103: }
104: }
105: }
106:
107: private void addEndpoints(Coordinate[] pts) {
108: add(pts[0]);
109: add(pts[pts.length - 1]);
110: }
111:
112: private void add(Coordinate point) {
113: double dist = point.distance(centroid);
114: if (dist < minDistance) {
115: interiorPoint = new Coordinate(point);
116: minDistance = dist;
117: }
118: }
119:
120: }
|