osmdroid坐标捕捉

时间:2016-07-20 15:22:25

标签: android rotation osmdroid utm

我们目前正在尝试为osmdroid开发一种航路点系统。用户可以放置依赖于用户当前正在进行的建筑物的航路点 建筑物数据包括一个角度,因此航路点之间的所有线路都是相对于原始角度的90°的倍数。例如,如果建筑角度(与水平线相比测量)为20.5°,则所有航点连接应为20.5°,110.5°,200.5°或290.5°。拖动航点时,航点位置应按照触点与任意有效角度之间的最短角度捕捉到方向。
我们制定了一个算法,该算法采用触摸坐标和最后一个航点,比较坐标并计算它们之间的角度,将它们转换为原点,围绕获得90°倍数所需的最小角度旋转并向后平移。算法本身似乎是有效的,但有时候,线条变得“曲线”,而osmdroid似乎会让路点在拖动时获得跳跃。这些飞跃非常小,但在查看整个地图时非常明显。 这是捕捉航点坐标的代码:

    public static GeoPoint getSnappedCoordinates(Waypoint w, double[] touchCoordinatesUTM, double mapRotation) {
    double[] parentWaypoint = w.getUTMCoordinatesAsDoubleArray();

    // Angle to x-axis
    double touchAngle = getAngleBetweenTwoPointsWithFixedPoint(touchCoordinatesUTM, new double[]{parentWaypoint[0], parentWaypoint[1]+1}, parentWaypoint);

    // set up valid degrees
    ArrayList<Double> validDegrees = new ArrayList<>();

    if (mapRotation < 0)
        mapRotation = 360 + mapRotation;

    double curDeg = mapRotation;

    while (!validDegrees.contains(curDeg)) {
        validDegrees.add(curDeg);
        curDeg += deg;
        curDeg %= 360;
    }

    // get closest valid angle
    double minAngleDist = Double.POSITIVE_INFINITY;

    for (Double d : validDegrees) {
        double curDist = Math.abs(d - touchAngle);
        if (curDist < Math.abs(minAngleDist)) {
            minAngleDist = d - touchAngle;
        }
    }

    minAngleDist = GeoTransform.deg2rad(minAngleDist);

    // translate to origin
    double translatedX = touchCoordinatesUTM[0] - parentWaypoint[0];
    double translatedY = touchCoordinatesUTM[1] - parentWaypoint[1];

    // rotate
    double[] pointR = {parentWaypoint[0] + translatedX * Math.cos(minAngleDist) - translatedY*Math.sin(minAngleDist),
            parentBeacon[1] + translatedX*Math.sin(minAngleDist) + translatedY*Math.cos(minAngleDist)};

    double[] res = GeoTransform.UTMXYToLatLon(pointR[1], pointR[0], 32, false);

    // return rotated GeoPoint
    GeoPoint p = new GeoPoint(GeoTransform.rad2deg(res[0]), GeoTransform.rad2deg(res[1]));
    return p;
}

GeoTransform级是第三方,不是我们编写的。 This is a picture of the error. 很容易看出,所有航点产生的直线都不是直的,建筑角度应该在3°左右。问题是,航点连接角度远不一致。以下是我们已经尝试消除错误的一些事项:
1.产生一条斜率等于建筑物角度的直线并计算y位置而不是旋转坐标
2.旋转屏幕像素而不是UTM坐标,让地图投影在像素和LatLon之间转换(以查看错误是否来自GeoTransform)

根本没有任何帮助甚至改变错误。无论我们做了什么,航点都会在拖动它们时采取这些小跳跃,并且它们产生的线不会是直的。 我们使用XML序列化这些航路点,并且LatLon坐标在大多数情况下都是这样的:

    <GeoPoint>
        <Lat>X.489174999999996</Lat>
        <Lon>X.404693999999999</Lon>
    </GeoPoint>

(用x替换实际的latlon值) 这看起来像一个双十进制错误。大多数这些航路点的小数点都有“99999”。上述解决方案没有改变任何有关该方面的内容。如所预期的那样,打印所得到的角度导致不同的角度,从90°到最大0.02。我们的航点扩展了Marker类,我们在OnMarkerDragListener中设置了位置,实现如下:

                double[] eventPosUTM = GeoTransform.ell2utm(eventPos.getLatitude(), eventPos.getLongitude());
            marker.setPosition(getSnappedCoordinates(marker.getConnectedEdges().get(0).getOtherWaypoint(marker), eventPosUTM, marker.getLevel().getRotationDeg()));

我们现在处理边缘的方式或多或少是典型的,应用程序应该只是后端,由知道如何实现的用户处理。 当用户可以拖动这些航点并且应用程序应该捕捉它们时,有关如何使用osmdroid使用多个latlon航点生成直线的任何想法?

0 个答案:

没有答案