假设我想用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;
}
}
答案 0 :(得分:1)
这适用于SQL,我希望您可以使用相同或类似的方法。
理论上,在这种情况下,你可以创建一个包含两个几何和你的“不可通过”几何的ConvexHull。
Geometry convexHull = sGeom1.STUnion(sGeom2).STUnion(split).STConvexHull();
接下来,将ConvexHull的边框提取为线串(使用STGeometry(1) - 我认为)。
Geometry convexHullBorder = convexHull.STGeometry(1);
编辑:实际上,使用几何图形,您可以使用STExteriorRing()。
Geometry convexHullBorder = convexHull.STExteriorRing();
最后,选择一个几何体,对于具有ConvexHull边框的每个共享点,从该点走到边界,直到到达与另一个几何体共享的第一个点,添加当前和到达每个点的前一点。如果您击中的第二个点属于与您行走时相同的几何图形,请退出循环并继续前进到下一个点以缩短时间。重复第二个几何体。
当您为所有可能性完成此操作时,您可以简单地采用最小值(只有两个 - Geom1到Geom2和Geom2到Geom1)并且有你的答案。
当然,有很多场景过于简单,但如果所有场景中只有一个“墙”,它就会起作用。
关于它不起作用的一些想法:
希望有道理吗?
编辑:实际上,在进一步反射时,还有其他场景,其中ConvexHull方法不起作用,例如,多边形的形状可能导致ConvexHull不能生成几何体之间的最短路径“墙”。这不会让你100%准确。