Создайте большой круг в openlayers 5 - PullRequest
0 голосов
/ 30 ноября 2018

Мне нужно создать круг с радиусом Х в метрах, учитывающий кривизну Земли.В 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 голосов
/ 11 декабря 2018

Если вам нужна функция 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 ()

...