1

我有 3 条线定义为线 A、线 B 和线 C,并且想计算线 B 和 C 与 A 之间的交点。从 JTS 有一个函数LineIntersector应该有助于实现这一点。我需要帮助将此函数应用于线条以找到交点,即。像 computeIntersection(line A, line B) 之类的东西。谢谢!

import com.vividsolutions.jts.geom.*;
import com.vividsolutions.jts.algorithm.*;

public class PointTest {

public static void main(String[] args){

// We have to have an even number of arguments - to have coordinate pairs for points.

if (args.length % 2 == 1) {
  System.out.println("Wrong input. You did not enter a list of coordinage pairs. Try again.");
}


else {

  int i=0;
  String[] coordA = {"12", "2", "12", "13", "12", "19"};
  String[] coordB = {"2", "10", "10", "10", "21", "11"};
  String[] coordC = {"1","1", "9","9", "20", "20"};





  // Create a new empty array of coordinates.

  //Coordinate[] coordinates = new Coordinate[args.length/2];     

  Coordinate[] coordinatesA = new Coordinate[coordA.length/2];
  Coordinate[] coordinatesB = new Coordinate[coordB.length/2];
  Coordinate[] coordinatesC = new Coordinate[coordC.length/2];
  // Go through the args and add each point as a Coordinate object to the coordinates array.

  //Geometry g1 = new GeometryFactory().createLineString(coordinatesA);

  //System.out.println(g1);

      while (i < coordA.length) {
    // transform string arguments into double values
    double x = Double.parseDouble(coordA[i]);
    double y = Double.parseDouble(coordA[i+1]);
    double xx = Double.parseDouble(coordB[i]);
    double yy = Double.parseDouble(coordB[i+1]);
    double xxx = Double.parseDouble(coordC[i]);
    double yyy = Double.parseDouble(coordC[i+1]);
    // create a new Coordinate object and add it to the coordinates array
    Coordinate newCoord = new Coordinate(x,y);
    coordinatesA[i/2] = newCoord;
    Coordinate newCoordB = new Coordinate(xx,yy);
    coordinatesB[i/2] = newCoordB;
    Coordinate newCoordC = new Coordinate(xxx,yyy);
    coordinatesC[i/2] = newCoordC;
    //System.out.println(newCoordB.toString());    
    i=i+2;
  } // while

  // Create a new Geometry from the array of coordinates.
  LineString lineA = new GeometryFactory().createLineString(coordinatesA);
  LineString lineB = new GeometryFactory().createLineString(coordinatesB);
  LineString lineC = new GeometryFactory().createLineString(coordinatesC);
  System.out.println("Line A is "+ lineA);
  System.out.println("Line B is "+ lineB);
  System.out.println("Line C is "+ lineC);

  // Read the start and end point of the line and write them on the screen.
  Point startPointA = lineA.getStartPoint();
  Point endPointA = lineA.getEndPoint();
  //System.out.println("The start point of the line is: " + startPointA.toString());    
  //System.out.println("The end point of the line is: " + endPointA.toString());


} // else

 } //main   

 }      
4

3 回答 3

3

在使用此 API 方面,我可能比新手高出一个档次,但您的问题与我一直在研究的问题很接近,我可以分享我迄今为止发现的问题。我的问题是两个LineStrings,找到它们相交的点。我已经用LineIntersector来解决我的问题——它也可以解决你的问题——但是了解LineIntersector有助于解决的更一般的问题是很好的。

您要区分的第一个区别是两者LineString交叉还是相交。交叉时,没有Coordinate共享的 s,但连接至少两对Coordinates 的线彼此跨越。如果两个LineStrings 相交,则其中一个 s 上会有一个点LineString落在“容差”范围内。我使用该buffer()方法来指定匹配的容差:

if (lineStringA.buffer(0.0001).intersects(lineStringB)) { ... }

同样对于测试(限制较少的)交叉:

if (lineStringA.buffer(0.0001).crosses(lineStringB)) { ... }

如果两个LineStrings 相交,我发现遍历每个坐标是直截了当的,直到找到位于第二个坐标上的第一个LineString。那个共同点就是交叉点。

如果两个LineStrings交叉但不相交,我会拿出LineIntersector.computeIntersection()方法来帮忙,但是这个方法的接口需要一些准备LineString才能找到合适Coordinate的s来使用。

这是我用来走第一个LineString找到穿过第二个点的两个点的方法LineString

private LineString findCrossingPair(LineString workingLineString,
        LineString fixedLineString) {
    // Pick up our factory instance
    GeometryFactory factory = fixedLineString.getFactory();

    Coordinate[] coordinates = workingLineString.getCoordinates();
    int length = coordinates.length;
    int indexOfCrossing = 0;

    // Walk the workingLineString for as long as it crosses the fixedLineString
    for (int i = 1; workingLineString.crosses(fixedLineString)
            && i < (length - 1); i++) {
        workingLineString = factory.createLineString(
                Arrays.copyOfRange(coordinates, i, length));
        indexOfCrossing = i;
    }

    Coordinate[] crossingPair = Arrays.copyOfRange(coordinates,
            indexOfCrossing - 1, indexOfCrossing + 1);
    LineString crossingPiece = factory.createLineString(crossingPair);

    return crossingPiece;
}

我调用它一次以找到第一对Coordinates(返回为 a LineString),然后将其转过来与第二个LineString. 这是一个调用该findCrossingPair()方法两次以获取两对坐标的示例:

    LineString firstPiece = findCrossingPair(LineStringA,
            LineStringB);
    LineString secondPiece = findCrossingPair(LineStringB,
            firstPiece);

    // Now we have two 2-point LineStrings which we can pass to the
    // LineIntersector

    LineIntersector lineIntersector = new RobustLineIntersector();
    lineIntersector.computeIntersection(
            firstPiece.getStartPoint().getCoordinate(),
            firstPiece.getEndPoint().getCoordinate(),
            secondPiece.getStartPoint().getCoordinate(),
            secondPiece.getEndPoint().getCoordinate()
            );
    Coordinate intersect = lineIntersector.getIntersection(0);
    System.out.println("Intersection at " + intersect);

请注意,在一般情况下,LineIntersector可以找到 0、1 或 2 个相交点。这就是LineIntersector接口具有传递给getIntersection()方法的索引的原因。交叉与相交的测试限制了此过程可以找到的交叉点的数量。

于 2015-09-26T15:09:05.993 回答
1

任何几何对象都具有可用的几何功能。您可以简单地使用geometryA.intersection(geometryB). 例如:

Geometry ab = lineA.intersection(lineB);
Geometry ac = lineA.intersection(lineC);

如果您想将结果组合到一个对象中,您可以使用数组GeometryFactory#createGeometryCollection或测试您获得的几何类型,然后将它们相应地组合为 MultiPoint。

于 2015-08-31T09:37:59.410 回答
1

在查看@bugmenot123 的答案后,我了解到我还有更多要学习的东西,但我能够将这些放在一起,使用 bugmenot123 的方法回答了这个问题。

我还不清楚在什么情况下我需要冗长而复杂的解决方案,但这里有一个似乎可以正常工作的已发布问题的解决方案:

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LineString;

public class LineStringIntersect {

    static Coordinate[] coordinateArrayA = {
            new Coordinate(12.0, 2.0),
            new Coordinate(12.0, 13.0),
            new Coordinate(12.0, 19.0)
    };

    static Coordinate[] coordinateArrayB = {
            new Coordinate(2.0, 10.0),
            new Coordinate(10.0, 10.0),
            new Coordinate(21.0, 11.0)
    };

    static Coordinate[] coordinateArrayC = {
            new Coordinate(1.0, 1.0),
            new Coordinate(9.0, 9.0),
            new Coordinate(20.0, 20.0)
    };

    static GeometryFactory geometryFactory = new GeometryFactory();

    static LineString lineStringA = geometryFactory
            .createLineString(coordinateArrayA);
    static LineString lineStringB = geometryFactory
            .createLineString(coordinateArrayB);
    static LineString lineStringC = geometryFactory
            .createLineString(coordinateArrayC);

    static Geometry geometryAB = lineStringA.intersection(lineStringB);
    static Geometry geometryAC = lineStringA.intersection(lineStringC);
    static Geometry geometryBC = lineStringB.intersection(lineStringC);

    public static void main(String args[]) {
        System.out.println("AB: " + geometryAB);
        System.out.println("AC: " + geometryAC);
        System.out.println("BC: " + geometryBC);
    }

}
于 2015-10-01T01:57:30.923 回答