2014-02-24 33 views
0

假设我想要计算两个几何体之间的距离与JTS,但是中间还有一个我不能穿过的距离(就好像它是一堵墙)。它看起来是这样的:JTS:两个几何体之间的距离绕过另一个在中间

Two polygons with one linestring in the middle

我不知道我怎么能计算出。

在这种情况下,这些形状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.5, 299647.3623194871 5721073.557249224, 299682.8494029705 5721049.148841454, 299668.20990794065 5721092.5))";  
    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; 
     } 

}

回答

1

这适用于SQL,我希望你有在您的处置相同或类似的方法。

理论上,在这种情况下,您可以创建一个ConvexHull,其中包含两个几何形状和“不可通过的”几何体。接下来,将ConvexHull的边界提取到一个线串(使用STGeometry(1) - 我认为)。

Geometry convexHullBorder = convexHull.STGeometry(1); 

编辑:其实,与几何您可以使用STExteriorRing()。

几何convexHullBorder = convexHull.STExteriorRing();

最后,选择其中一个几何图形,并为每个带有ConvexHull边框的共享点,从该点走过边框,直到达到与另一个几何图元共享的第一个点,然后添加当前并在每个点达到​​前一点。如果您点击的第二个点与您走过的几何图形属于同一个几何图形,请退出循环并转至下一个点以缩短时间。重复第二个几何体。

当您完成所有可能性时,您可以简单地取最小值(将只有两个 - Geom1到Geom2和Geom2到Geom1),并且有答案。

当然,这很简单,但如果所有场景中都只有一个“墙”,它就会起作用。

的,它不会工作的一些想法:

  • 的“墙”是一个多边形,完全包围两个几何 - 但后来你会怎么过那里呢?
  • 有多个彼此不相交的“墙壁”(它们之间的空隙) - 此方法将忽略“墙壁”之间的那些通道。但是,如果多个“墙壁”相交,创造出一个更大的“墙”,这个理论仍然有效。

希望有道理吗?

编辑:其实,在进一步思考的还有其他场景中的凸形轮廓的做法是行不通的,比如你的多边形的形状可能导致凸形轮廓不产生几何形状和你的“墙”之间的最短路径。这不会让你100%准确。

+0

这太棒了,乔恩。我认为它适合我的实际要求。使用我使用的Java库的JTS进行编码应该很容易。非常感谢你。 – krause

+0

@krause我们非常欢迎您,很高兴我能提供帮助。 –

相关问题