【问题标题】:Perpendicular Point Placement垂直点放置
【发布时间】:2020-06-21 12:47:10
【问题描述】:

我有一条在地球上具有起点和终点坐标的线。
我试图在起点 length 距离的每一侧放置垂直点。

本来以为可以

  • 获取直线的斜率
  • 确定起点处垂线的斜率
  • 求解 x 和 y
Coordinate p1 = Ppoint(start, end, length); 
Coordinate p2 = Ppoint(start, end, -(length)); 

public static Coordinate Ppoint(Coordinate start, Coordinate end, double length){
   double slope = getSlope(start, end);
   double pSlope;  
   if(slope != 0)
   {
      pSlope = -(1/slope); 
   } 
   else 
   { 
      pSlope = 0; 
   }

   double b = start.y + (-(pSlope * start.x)); 

   double x = (start.x + length);
   double y = (pSlope * x) + b; 

   Return new Coordinate(x,y); 
}

我认为在纬度/经度上进行数学计算并考虑它们的范围存在问题
这并不能说明地球不是平坦的。
有没有更好的方法来解决这个问题?

【问题讨论】:

  • 线和长度是多少?
  • @IanTurton 该行是任意长度的。长度只是一个选择的设定值(正在玩 .005)

标签: java coordinates latitude-longitude geo geotools


【解决方案1】:

地球不是平的?

好的,this 网站会比我更好地解释如何使用 sphere。您正在寻找的是:给定起点、距离和方位的目标点

您也可以将坐标系更改为平面坐标系,这并不可惜。 https://epsg.io/

【讨论】:

    【解决方案2】:

    您可能不应该尝试在球体上进行此类数学运算(虽然它可以工作,但它既难又慢)。

    假设length 大约是 10 到 100 公里,您应该将问题重新投影到以起点为中心的“平坦”表面,并在平面上使用欧几里得数学。

    幸运的是,GeoTools 为这个问题提供了方便的自动投影。这里x & y是起点坐标(lon==x, lat==y):

    String code = "AUTO:42001," + y + "," + x;
    // System.out.println(code);
    CoordinateReferenceSystem auto = CRS.decode(code);
    // System.out.println(auto);
    MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84,
        auto);
    MathTransform rTransform = CRS.findMathTransform(auto, DefaultGeographicCRS.WGS84);
    

    然后您可以使用transform 对象将您的点转换为新的投影:

    Geometry g3 = JTS.transform(g1, transform);
    

    做任何你需要的数学,然后使用rTransform转换回纬度,经度

    所以为了适应你的问题。

    Coordinate start = new Coordinate(1.0, 51.0);
    Coordinate end = new Coordinate(2.0, 52.0);
    double length = 10000;
    GeometryFactory gf = new GeometryFactory();
    
    double x = start.getX();
    double y = start.getY();
    String code;
    if(CRS.getAxisOrder(DefaultGeographicCRS.WGS84).equals(AxisOrder.EAST_NORTH)) {
      code = "AUTO:42001," + x + "," + y;
    } else {
      code = "AUTO:42001," + y + "," + x;
    }
    CoordinateReferenceSystem auto = CRS.decode(code);
    MathTransform transform = CRS.findMathTransform(DefaultGeographicCRS.WGS84, auto);
    MathTransform rTransform = CRS.findMathTransform(auto, DefaultGeographicCRS.WGS84);
    
    Point pStart = gf.createPoint(start);
    Point pEnd = gf.createPoint(end);
    
    Point ptStart = (Point) JTS.transform(pStart, transform);
    Point ptEnd = (Point) JTS.transform(pEnd, transform);
    
    Coordinate p1 = pPoint(ptStart.getCoordinate(), ptEnd.getCoordinate(), length);
    
    Point tPoint = gf.createPoint(p1);
    Point p = (Point) JTS.transform(tPoint, rTransform);
    System.out.println(p);
    

    这给了我POINT (1.2643 47.6531),这对我来说看起来不对!您可能需要检查 pPoint 方法中的数学运算。

    【讨论】:

    • 使用 start.x() 和 start.y() 作为 x & y。在开始和结束时使用变换,然后在变换点上调用 pSlope 方法
    • 啊,感谢您的编辑,您对 Ppoint 的看法是正确的(已更新)。坐标正在工作,只需要测试世界各地的一些线路:)
    猜你喜欢
    • 2011-04-29
    • 2013-08-16
    • 2018-09-08
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-05
    • 1970-01-01
    相关资源
    最近更新 更多