使用纬度和经度计算多边形面积

5
我正在使用在这篇帖子中找到的解决方案:使用从笛卡尔空间和世界文件生成的经纬度计算多边形面积

丹佛橄榄球场

有些地方出现了问题,因为我得到的值不是真实的。例如,我们知道一个足球场应该有大约5,300.00平方米,对吧?但是计算出来的是5,759,154.21。

这是代码:

    private static double CalculatePolygonArea(IList<Position> coordinates)
    {
        double area = 0;

        if (coordinates.Count > 2)
        {
            for (var i = 0; i < coordinates.Count - 1; i++)
            {
                Position p1 = coordinates[i];
                Position p2 = coordinates[i + 1];
                area += (ConvertToRadian(p2.Longitude) - ConvertToRadian(p1.Longitude)) * (2 + Math.Sin(ConvertToRadian(p1.Latitude)) + Math.Sin(ConvertToRadian(p2.Latitude)));
            }

            area = area * 6378137 * 6378137 / 2;
        }

        return Math.Abs(area);
    }

    private static double ConvertToRadian(double input)
    {
        return input * Math.PI / 180;
    }

这里可能出了什么问题?需要帮助吗?

1
你的四个点的值是什么? - Jason
1个回答

8
你正在使用的区域计算方法是完全错误的.... :-/
我使用了谷歌的Android Maps Utils中的SphericalUtil.ComputeSignedArea 方法。
注意:谷歌的Java代码采用Apache许可证版本2.0,我将其转换为C#。
在我的一个应用程序中查找那个足球场,我得到了4,461,虽然不是实际的5,531,但对于使用谷歌地图照片来说还不错...

enter image description here

这里只是 ComputeSignedArea:
public static class SphericalUtil
{
    const double EARTH_RADIUS = 6371009;

    static double ToRadians(double input)
    {
        return input / 180.0 * Math.PI;
    }

    public static double ComputeSignedArea(IList<LatLng> path)
    {
        return ComputeSignedArea(path, EARTH_RADIUS);
    }

    static double ComputeSignedArea(IList<LatLng> path, double radius)
    {
        int size = path.Count;
        if (size < 3) { return 0; }
        double total = 0;
        var prev = path[size - 1];
        double prevTanLat = Math.Tan((Math.PI / 2 - ToRadians(prev.Latitude)) / 2);
        double prevLng = ToRadians(prev.Longitude);

        foreach (var point in path)
        {
            double tanLat = Math.Tan((Math.PI / 2 - ToRadians(point.Latitude)) / 2);
            double lng = ToRadians(point.Longitude);
            total += PolarTriangleArea(tanLat, lng, prevTanLat, prevLng);
            prevTanLat = tanLat;
            prevLng = lng;
        }
        return total * (radius * radius);
    }

    static double PolarTriangleArea(double tan1, double lng1, double tan2, double lng2)
    {
        double deltaLng = lng1 - lng2;
        double t = tan1 * tan2;
        return 2 * Math.Atan2(t * Math.Sin(deltaLng), 1 + t * Math.Cos(deltaLng));
    }
}

有时候很酷,对我起作用,但有时候却得到了负面的结果。我们应该只取结果的绝对值吗?还是还有其他情况?我的观点似乎被正确排序了,即第一个观点和最后一个观点是一样的。 - undefined
检查我的数字与已知值对比时,当我得到负数时,标量分量似乎准确且符合预期。因此,我在你的返回语句周围添加了Math.Abs。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接