/* Spatial Operations & Editing Tools for uDig
*
* Axios Engineering under a funding contract with:
* Diputación Foral de Gipuzkoa, Ordenación Territorial
*
* http://b5m.gipuzkoa.net
* http://www.axios.es
*
* (C) 2010, Diputación Foral de Gipuzkoa, Ordenación Territorial (DFG-OT).
* DFG-OT agrees to license under Lesser General Public License (LGPL).
*
* 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 es.axios.udig.ui.editingtools.precisionparallels.internal;
import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;
/**
*
* Contains commons/util algorithms used by the parallel classes.
*
* @author Aritz Davila (www.axios.es)
* @author Mauricio Pazos (www.axios.es)
*/
public final class AlgorithmUtils {
public static int forwardIntersectedSegmentsCounter(final LineString subjectLine,
final Coordinate[] subjectLineCoord,
int j,
int n,
Coordinate[] inputList,
GeometryFactory gf,
Coordinate intersectionCoord) {
// the segment that will be tested if intersects.
LineString interSegment = null;
Coordinate candidateCoord = null;
int counter = 0;
// make a complete turn and get with the last intersection that
// intersects with the provided segment.
for (int h = j;;) {
counter++;
h = (h + 1) % n;
// mount a segment.
Coordinate[] interCoord = new Coordinate[2];
interCoord[0] = inputList[h];
interCoord[1] = (h == n - 1) ? inputList[0] : inputList[h + 1];
interSegment = gf.createLineString(interCoord);
// get the intersection coordinate if it intersects.
candidateCoord = getIntersectionCoord(subjectLine, interSegment, subjectLineCoord);
if (candidateCoord != null && candidateCoord.equals2D(intersectionCoord)) {
break;
}
if (h == j) {
// if it has been checked all the segment and any intersection
// has been found, get out the loop and return nothing ??
break;
}
}
return counter;
}
public static int backwardIntersectedSegmentCounter(final Geometry subjectLine,
final Coordinate[] subjectLineCoord,
int j,
int n,
Coordinate[] inputList,
GeometryFactory gf,
Coordinate intersectionCoord) {
// the segment that will be tested if intersects.
LineString interSegment = null;
Coordinate candidateCoord = null;
int counter = 0;
// make a complete turn and get with the last intersection that
// intersects with the provided segment.
for (int h = j;;) {
counter++;
// mount a segment.
Coordinate[] interCoord = new Coordinate[2];
interCoord[0] = inputList[h];
interCoord[1] = (h == 0) ? inputList[n - 1] : inputList[h - 1];
interSegment = gf.createLineString(interCoord);
// get the intersection coordinate if it intersects.
candidateCoord = getIntersectionCoord(subjectLine, interSegment, subjectLineCoord);
if (candidateCoord != null && candidateCoord.equals2D(intersectionCoord)) {
break;
}
h = (h == 0) ? n - 1 : h - 1;
if (h == j) {
// if it has been checked all the segment and any intersection
// has been found, get out the loop and return nothing ??
break;
}
}
return counter;
}
/**
* Get the intersection coordinate if exist, otherwise will return null.
*
* @param firstSegment
* First segment to be checked.
* @param interSegment
* Second segment to be checked.
* @param firstSegC
* Both coordinates of the first segment.
* @return The coordinate or null if it doesn't exist.
*/
public static Coordinate getIntersectionCoord( final Geometry firstSegment,
final Geometry interSegment,
final Coordinate[] firstSegC) {
Coordinate candidateCoord = null;
// if intersects.
if (firstSegment.intersects(interSegment)) {
Geometry resultPoints = firstSegment.intersection(interSegment);
for (int k = 0; k < resultPoints.getNumGeometries(); k++) {
Coordinate intersectionCoord = resultPoints.getGeometryN(k).getCoordinate();
// check the intersection isn't the start and the end point of
// the segment.
if (!(firstSegC[1].equals2D(intersectionCoord)) && !(firstSegC[0].equals2D(intersectionCoord))) {
candidateCoord = new Coordinate(intersectionCoord);
break;
}
}
}
return candidateCoord;
}
}