使用JTS从多个LineStrings计算交集

时间:2015-07-20 15:31:13

标签: java jts

我将3行定义为A行,B行和C行,并且想要计算B行和C行之间的交点。从JTS开始,有一个函数LineIntersector可以帮助实现这一点。我需要帮助将这个函数应用到线上以便找到交点,即。类似于computeIntersection(A行,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   

 }      

3 个答案:

答案 0 :(得分:1)

任何Geometry对象都具有可用的几何函数。您只需使用geometryA.intersection(geometryB)即可。例如:

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

如果要将结果合并到一个对象中,可以使用带有GeometryFactory#createGeometryCollection的数组,也可以测试您获得的几何类型,并将它们组合到例如MultiPoint中。

答案 1 :(得分:1)

我使用这个API可能比新手高出一点,但你的问题接近于我一直在努力的问题,我可以分享到目前为止我发现的内容。我的问题是两个LineString,找到它们相交的点。我使用LineIntersector来解决我的问题 - 它也可以解决你的问题 - 但是理解LineIntersector帮助解决的更普遍的问题是很好的。

您要做的第一个区别是两个LineString s 交叉是否相交。在交叉时,没有共享的Coordinate,但连接至少两对Coordinate的线相互跨越。如果两个LineString相交,则LineString中的一个上的点将出现在“容差”范围内。我使用buffer()方法指定匹配的容差:

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

类似于测试(限制较少)的交叉:

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

如果两个LineString相交,我发现直接走过每个坐标,直到我发现第一个坐在第二个LineString上。这个共同点就是交叉点。

如果两个LineString交叉但不相交,我会得到LineIntersector.computeIntersection()方法来帮助,但是这个方法的接口需要对LineString进行一些准备。找到要使用的相应Coordinate

这是我用来走第一个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(作为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()方法的索引的原因。交叉与交叉的测试限制了此过程可以找到的交叉点的数量。

答案 2 :(得分: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);
    }

}