2014-02-24 79 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我們非常歡迎您,很高興我能提供幫助。 –

相關問題