【问题标题】:JTS : distance between two geometries bypassing another one in the middleJTS:两个几何之间的距离绕过另一个中间的几何
【发布时间】:2014-02-24 23:11:51
【问题描述】:

假设我想用 JTS 计算两个几何图形之间的距离,但中间还有一个我不能穿过(好像是一堵墙)。它可能看起来像这样:

我想知道如何计算。

在这种情况下,这些形状 geom1 和 geom2 距离为 38.45 米,因为我是直接计算出来的。但如果我不想越过那条线,我应该从北边围起来,距离大概有70多米。

我们可以认为我们可以在中间有一条线、一个多边形或其他任何东西。

我想知道 JTS 中是否有任何内置函数,或者我能告诉你的其他东西。我想如果有什么问题,我应该检查一下其他解决方法,因为尝试解决复杂的路由问题超出了我的知识范围。

这是一段直接使用 JTS 作为距离的代码,它仍然不会考虑中间的几何。

  import org.apache.log4j.Logger;
  import com.vividsolutions.jts.geom.Geometry;
  import com.vividsolutions.jts.io.ParseException;
  import com.vividsolutions.jts.io.WKTReader;

  public class distanceTest {

  private final static Logger logger = Logger.getLogger("distanceTest");

  public static void main(String [] args) {
    //Projection : EPSG:32631
    // We build one of the geometries on one side
    String sGeom1="POLYGON ((299621.3240601513 5721036.003245114, 299600.94820609683 5721085.042327096, 299587.7719688322 5721052.9152064435, 299621.3240601513 5721036.003245114))";
    Geometry geom1=distanceTest.buildGeometry(sGeom1);

    // We build the geometry on the other side
    String sGeom2=
            "POLYGON ((299668.20990794065 5721092.766132105, 299647.3623194871 5721073.557249224, 299682.8494029705 5721049.148841454, 299668.20990794065 5721092.766132105))";     
    Geometry geom2=distanceTest.buildGeometry(sGeom2);

    // There is a geometry in the middle, as if it was a wall
    String split=
            "LINESTRING (299633.6804935104 5721103.780167559, 299668.99872434285 5720999.981241705, 299608.8457218057 5721096.601805294)";      
    Geometry splitGeom=distanceTest.buildGeometry(split);

    // We calculate the distance not taking care of the wall in the middle
    double distance = geom1.distance(geom2);
    logger.error("Distance : " + distance);
}

  public static Geometry buildGeometry(final String areaWKT) {
        final WKTReader fromText = new WKTReader();
        Geometry area;
        try {
          area = fromText.read(areaWKT);
        }
        catch (final ParseException e) {
          area = null;
        }
        return area;
      }

}

【问题讨论】:

    标签: geometry distance geospatial spatial jts


    【解决方案1】:

    这适用于 SQL,我希望你有相同或相似的方法供你使用。

    理论上,在这种情况下,您可以创建一个包含两个几何图形和“不可通过”几何图形的 ConvexHull。

    Geometry convexHull = sGeom1.STUnion(sGeom2).STUnion(split).STConvexHull();  
    

    接下来,将 ConvexHull 的边框提取为线串(我认为使用 STGeometry(1))。

    Geometry convexHullBorder = convexHull.STGeometry(1);
    

    编辑:实际上,对于 Geometry,您可以使用 STExteriorRing()。

    几何体convexHullBorder = convehull.SExteriorRing();

    最后,选择一个几何图形,对于每个与 ​​ConvexHull 的边界共享的点,从该点沿边界走,直到到达与其他几何图形共享的第一个点,添加当前与 ConvexHull 边界之间的距离到达每个点的前一个点。如果您击中的第二个点与您行走时属于同一几何体,请退出循环并继续前进以减少时间。对第二个几何重复。

    当您为所有可能性都完成此操作后,您可以简单地取最小值(只有两个 - Geom1 到 Geom2 和 Geom2 到 Geom1),这就是您的答案。

    当然,有很多场景太简单了,但如果所有场景都只有一面“墙”,那就行了。

    关于它在哪里不起作用的一些想法:

    • “墙”是一个多边形,完全包围了两个几何图形 - 但是你怎么会到达那里呢?
    • 有多个不相交的“墙”(它们之间的间隙) - 此方法将忽略“墙”之间的那些通道。然而,如果多面“墙”相交,则基本上创建一堵更大的“墙”,该理论仍然有效。

    希望这有意义吗?

    编辑:实际上,经过进一步思考,在其他情况下 ConvexHull 方法将不起作用,例如多边形的形状可能导致 ConvexHull 无法在几何图形和您的几何图形之间生成最短路径“墙壁”。这不会让您获得 100% 的准确率。

    【讨论】:

    • 太棒了,乔恩。我认为它非常适合我的实际要求。使用我使用的 Java 库 JTS 进行编码应该很容易。非常感谢。
    猜你喜欢
    • 1970-01-01
    • 2019-06-19
    • 1970-01-01
    • 2016-05-11
    • 2021-06-03
    • 2014-05-31
    • 2014-06-08
    • 2018-06-14
    • 2014-11-12
    相关资源
    最近更新 更多