【问题标题】:Combine a sequence of LineString组合一系列 LineString
【发布时间】:2018-04-17 16:47:27
【问题描述】:

我有一个 LineString 序列,例如 lineString1lineString2

lineString1.getEndPoint() == lineString2.getStartPoint()lineString1.getStartPoint() == lineString2.getEndPoint() 我想得到LineString 对象(不是MultiLineString),它将结合lineString1lineString2

我没有找到任何好的解决方案。

【问题讨论】:

  • ineString1.getEndPoint() == lineString1.getStartPoint() 你确定你不是说lineString2.getStartPoint() 吗?
  • 是的,感谢您的关注

标签: java gis geotools


【解决方案1】:

您需要使用JTS LineMerger 来实现这一点,它返回一个Collection<LineString>,但在您的示例中,这是它们连接时的单行(在其他情况下,只有一些行可能会接触)。

import java.util.Collection;

import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.LineString;
import com.vividsolutions.jts.io.ParseException;
import com.vividsolutions.jts.io.WKTReader;
import com.vividsolutions.jts.operation.linemerge.LineMerger;

public class LineJoin {

  public static void main(String[] args) throws ParseException {
    /*String[] WKTS = { "LINESTRING (254058.76074485347 475001.2186020431, 255351.04293761664 474966.9279243938)",
        "LINESTRING (255351.04293761664 474966.9279243938, 255529.29662365236 474272.4599921228)",
        "LINESTRING (255529.29662365236 474272.4599921228, 256166.05830998957 473979.44920198264)",
        "LINESTRING (256166.05830998957 473979.44920198264, 256082.8878282134 472762.2531920295)",
        "LINESTRING (256082.8878282134 472762.2531920295, 254245.37250651795 472802.681197444)",
        "LINESTRING (254245.37250651795 472802.681197444, 254294.87550167093 473782.10435392085)",
        "LINESTRING (255802.5570897992 475306.663459122, 256973.3861333156 473826.71649389854)",
        "LINESTRING (256973.3861333156 473826.71649389854, 256996.781511873 472271.0759416939)",
        "LINESTRING (254134.08645022905 471750.25133671844, 253091.20265363617 473772.75685744354)",
        "LINESTRING (252764.19811300343 475015.97340571403, 253526.90397945273 476194.3201198712)",
        "LINESTRING (253526.90397945273 476194.3201198712, 254983.29259833007 475930.5996061625)" };*/
    String[] WKTS = {"LINESTRING(10 40,11 41)","LINESTRING(11 41,12 42)"};
    WKTReader reader = new WKTReader();
    LineMerger merger = new LineMerger();
    for (String wkt : WKTS) {
      Geometry geom = reader.read(wkt);
      merger.add(geom);
    }

    Collection<LineString> collection = merger.getMergedLineStrings();

    for (LineString l : collection) {
      System.out.println(l);
    }
  }

}

对于您的测试输入,它给出:

LINESTRING (10 40, 11 41, 12 42)

对于被注释掉的 WKT,你会得到:

LINESTRING (252764.19811300343 475015.97340571403, 253526.90397945273 476194.3201198712, 254983.29259833007 475930.5996061625)
LINESTRING (254134.08645022905 471750.25133671844, 253091.20265363617 473772.75685744354)
LINESTRING (254058.76074485347 475001.2186020431, 255351.04293761664 474966.9279243938, 255529.29662365236 474272.4599921228, 256166.05830998957 473979.44920198264, 256082.8878282134 472762.2531920295, 254245.37250651795 472802.681197444, 254294.87550167093 473782.10435392085)
LINESTRING (255802.5570897992 475306.663459122, 256973.3861333156 473826.71649389854, 256996.781511873 472271.0759416939)

【讨论】:

  • 非常感谢,是的,它适用于 LineMerger 类 :)
【解决方案2】:

您可以使用GeometryCollectionunion 方法加入LineStrings。请参阅文档here - 对于线条字符串的集合,它具有完全点头和溶解线条的效果。

static Geometry combineIntoOneGeometry( Collection<Geometry> geometryCollection ){
     GeometryFactory factory = FactoryFinder.getGeometryFactory( null );

     // note the following geometry collection may be invalid (say with overlapping polygons)
     GeometryCollection geometryCollection =
          (GeometryCollection) factory.buildGeometry( geometryCollection );

     return geometryCollection.union();
 }

【讨论】:

  • 谢谢,但“联合”并不是我所需要的。我通过检查 2 个 lineStrings 的开始和结束协调来找到共同的。如果需要 - 我将在之后创建 (LineString) lineGeometry.reverse(); ,只需将所有坐标放入数组:coordinates.addAll(Arrays.asList(lineGeometry.getCoordinates())); 并最终构建组合 LineString 对象:geometryFactory.createLineString(coordinates.toArray(new Coordinate[0]));
  • 我已经测试了combineIntoOneGeometry 方法。不幸的是,它返回 MultiLineString - 没有组合 1 个单一的 LineString。我写了简单的测试:LineString lineString1 = (LineString)getGeometry("LINESTRING(10 40,11 41)"); LineString lineString2 = (LineString)getGeometry("LINESTRING(11 41,12 42)"); Collection&lt;Geometry&gt; geometries = new ArrayList&lt;&gt;(); geometries.addAll(getGeometries(lineString1)); geometries.addAll(getGeometries(lineString2)); Geometry geometry = combineIntoOneGeometry(geometries); System.out.println(geometry);
  • 在 gis.stackexchange 上,Ian 回答了 a similar question,其中更详细地解释了联合和行合并之间的区别。
【解决方案3】:

关注geotool documentation

GeometryFactory geometryFactory = JTSFactoryFinder.getGeometryFactory();
LineString combinedLineString = GeometryFactory.createLineString(
    lineString1.getControlPoints()
        .addAll(lineString2.getControlPoints())
    );

【讨论】:

  • 只有当 lineString 包含 2 个点时才有效 - 开始和结束。但大多数情况下,它包含几个点,其中 LineString 不仅仅是一条普通的线。
  • 拥有类似geometryFactory.createLineString(MultiLineString)的方法会很酷
  • 那么combinedLineString = GeometryFactory.createLineString(lineString1.getControlPoints().addAll(lineString2.getControlPoints())); 是一个解决方案吗?
  • 这个解决方案真的可以与 JTS LineString 一起使用吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-21
  • 1970-01-01
  • 2020-02-17
  • 2017-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多