在openlayers 5中创建伟大的圈子

时间:2018-11-30 17:27:00

标签: openlayers-5

我需要创建一个半径为X的圆(以米为单位),以说明地球的曲率。 回到OpenLayers 2,我们有了destinationVincenty,它有助于从一个点计算出目的地,并考虑了角度。 但是,OpenLayers 5中似乎缺少此功能。

我已经测试了Cricle的几何形状,但是它太不精确了(检查图像)。

如何在OpenLayers 5中做到这一点?

The blue circle was drawn with 245km radius, but the actual 245km radius should go until about the red line near Sedalia.

绘制了一个半径为245公里的蓝色圆圈,但实际的245公里半径应一直到塞达利亚附近的红线附近。

1 个答案:

答案 0 :(得分:0)

如果需要destinationVincenty函数,可以很容易地从OL2源复制。 我已经添加了3个明显的依赖项,并将输入lonlat和返回值更改为OL3 / 4/5类型的坐标数组,但是尚未进行任何测试。

destinationVincenty = function(lonlat, brng, dist) {
    //var u = OpenLayers.Util;
    var u = {};
    u.rad = function(x) {return x*Math.PI/180;};
    u.deg = function(x) {return x*180/Math.PI;};
    u.VincentyConstants = {
        a: 6378137,
        b: 6356752.3142,
        f: 1/298.257223563
    };

    var ct = u.VincentyConstants;
    var a = ct.a, b = ct.b, f = ct.f;

    var lon1 = lonlat[0]; //lonlat.lon;
    var lat1 = lonlat[1]; //lonlat.lat;

    var s = dist;
    var alpha1 = u.rad(brng);
    var sinAlpha1 = Math.sin(alpha1);
    var cosAlpha1 = Math.cos(alpha1);

    var tanU1 = (1-f) * Math.tan(u.rad(lat1));
    var cosU1 = 1 / Math.sqrt((1 + tanU1*tanU1)), sinU1 = tanU1*cosU1;
    var sigma1 = Math.atan2(tanU1, cosAlpha1);
    var sinAlpha = cosU1 * sinAlpha1;
    var cosSqAlpha = 1 - sinAlpha*sinAlpha;
    var uSq = cosSqAlpha * (a*a - b*b) / (b*b);
    var A = 1 + uSq/16384*(4096+uSq*(-768+uSq*(320-175*uSq)));
    var B = uSq/1024 * (256+uSq*(-128+uSq*(74-47*uSq)));

    var sigma = s / (b*A), sigmaP = 2*Math.PI;
    while (Math.abs(sigma-sigmaP) > 1e-12) {
        var cos2SigmaM = Math.cos(2*sigma1 + sigma);
        var sinSigma = Math.sin(sigma);
        var cosSigma = Math.cos(sigma);
        var deltaSigma = B*sinSigma*(cos2SigmaM+B/4*(cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)-
            B/6*cos2SigmaM*(-3+4*sinSigma*sinSigma)*(-3+4*cos2SigmaM*cos2SigmaM)));
        sigmaP = sigma;
        sigma = s / (b*A) + deltaSigma;
    }

    var tmp = sinU1*sinSigma - cosU1*cosSigma*cosAlpha1;
    var lat2 = Math.atan2(sinU1*cosSigma + cosU1*sinSigma*cosAlpha1,
        (1-f)*Math.sqrt(sinAlpha*sinAlpha + tmp*tmp));
    var lambda = Math.atan2(sinSigma*sinAlpha1, cosU1*cosSigma - sinU1*sinSigma*cosAlpha1);
    var C = f/16*cosSqAlpha*(4+f*(4-3*cosSqAlpha));
    var L = lambda - (1-C) * f * sinAlpha *
        (sigma + C*sinSigma*(cos2SigmaM+C*cosSigma*(-1+2*cos2SigmaM*cos2SigmaM)));

    var revAz = Math.atan2(sinAlpha, -tmp);  // final bearing

    //return new OpenLayers.LonLat(lon1+u.deg(L), u.deg(lat2));
    return [lon1+u.deg(L), u.deg(lat2)];
};

可用的最接近的方法是OL3 / 4/5,是ol.geom.Polygon.circular()