有谁知道获取一对经度和纬度点的中点的最佳方法?

我使用d3.js在 map 上绘制点,并且需要在两点之间绘制一条曲线,因此我需要创建一个中点以在直线上绘制曲线。

请查看下面的图片,以更好地了解我要执行的操作:

最佳答案

为冗长的脚本道歉-画东西似乎很有趣:-)。我已经标出了不需要的部分

// your latitude / longitude
var co2 = [70, 48];
var co1 = [-70, -28];


// NOT REQUIRED
var ctx = document.getElementById("myChart").getContext("2d");

function drawPoint(color, point) {
    ctx.fillStyle = color;
    ctx.beginPath();
    ctx.arc(point.x, point.y, 5, 0, 2 * Math.PI, false);
    ctx.fill();
}

function drawCircle(point, r) {
    ctx.strokeStyle = 'gray';
    ctx.setLineDash([5, 5]);
    ctx.beginPath();
    ctx.arc(point.x, point.y, r, 0, 2 * Math.PI, false);
    ctx.stroke();
}


// REQUIRED
// convert to cartesian
var projection = d3.geo.equirectangular()

var cot1 = projection(co1);
var cot2 = projection(co2);

var p0 = { x: cot1[0], y: cot1[1] };
var p1 = { x: cot2[0], y: cot2[1] };


// NOT REQUIRED
drawPoint('green', p0);
drawPoint('green', p1);


// REQUIRED
function dfn(p0, p1) {
    return Math.pow(Math.pow(p0.x - p1.x, 2) + Math.pow(p0.y - p1.y, 2), 0.5);
}

// from http://math.stackexchange.com/a/87374
var d = dfn(p0, p1);
var m = {
    x: (p0.x + p1.x) / 2,
    y: (p0.y + p1.y) / 2,
}

var u = (p1.x - p0.x) / d
var v = (p1.y - p0.y) / d;

// increase 1, if you want a larger curvature
var r = d * 1;
var h = Math.pow(Math.pow(r, 2) - Math.pow(d, 2) / 4, 0.5);

// 2 possible centers
var c1 = {
    x: m.x - h * v,
    y: m.y + h * u
}
var c2 = {
    x: m.x + h * v,
    y: m.y - h * u
}


// NOT REQUIRED
drawPoint('gray', c1)
drawPoint('gray', c2)

drawCircle(c1, r)
drawCircle(c2, r)


// REQUIRED

// from http://math.stackexchange.com/a/919423
function mfn(p0, p1, c) {
    // the -c1 is for moving the center to 0 and back again
    var mt1 = {
        x: r * (p0.x + p1.x - c.x * 2) / Math.pow(Math.pow(p0.x + p1.x - c.x * 2, 2) + Math.pow(p0.y + p1.y - c.y * 2, 2), 0.5)
    };
    mt1.y = (p0.y + p1.y - c.y * 2) / (p0.x + p1.x - c.x * 2) * mt1.x;

    var ma = {
        x: mt1.x + c.x,
        y: mt1.y + c.y,
    }

    var mb = {
        x: -mt1.x + c.x,
        y: -mt1.y + c.y,
    }

    return (dfn(ma, p0) < dfn(mb, p0)) ? ma : mb;
}

var m1 = mfn(p0, p1, c1);
var m2 = mfn(p0, p1, c2);

var mo1 = projection.invert([m1.x, m1.y]);
var mo2 = projection.invert([m2.x, m2.y]);


// NOT REQUIRED
drawPoint('blue', m1);
drawPoint('blue', m2);

// your final output (in lat long)
console.log(mo1);
console.log(mo2);

fiddle -https://jsfiddle.net/srjuc2gd/



这只是相关的部分(大部分只是该答案开头的copy-pasta)
var Q31428016 = (function () {

    // adjust curvature
    var CURVATURE = 1;


    // project to convert from lat / long to cartesian
    var projection = d3.geo.equirectangular();

    // distance between p0 and p1
    function dfn(p0, p1) {
        return Math.pow(Math.pow(p0.x - p1.x, 2) + Math.pow(p0.y - p1.y, 2), 0.5);
    }

    // mid point between p0 and p1
    function cfn(p0, p1) {
        return {
            x: (p0.x + p1.x) / 2,
            y: (p0.y + p1.y) / 2,
        }
    }

    // get arc midpoint given end points, center and radius - http://math.stackexchange.com/a/919423
    function mfn(p0, p1, c, r) {

        var m = cfn(p0, p1);

        // the -c1 is for moving the center to 0 and back again
        var mt1 = {
            x: r * (m.x - c.x) / Math.pow(Math.pow(m.x - c.x, 2) + Math.pow(m.y - c.y, 2), 0.5)
        };
        mt1.y = (m.y - c.y) / (m.x - c.x) * mt1.x;

        var ma = {
            x: mt1.x + c.x,
            y: mt1.y + c.y,
        }

        var mb = {
            x: -mt1.x + c.x,
            y: -mt1.y + c.y,
        }

        return (dfn(ma, p0) < dfn(mb, p0)) ? ma : mb;
    }

    var Q31428016 = {};
    Q31428016.convert = function (co1, co2) {

        // convert to cartesian
        var cot1 = projection(co1);
        var cot2 = projection(co2);

        var p0 = { x: cot1[0], y: cot1[1] };
        var p1 = { x: cot2[0], y: cot2[1] };


        // get center - http://math.stackexchange.com/a/87374
        var d = dfn(p0, p1);
        var m = cfn(p0, p1);

        var u = (p1.x - p0.x) / d
        var v = (p1.y - p0.y) / d;

        var r = d * CURVATURE;
        var h = Math.pow(Math.pow(r, 2) - Math.pow(d, 2) / 4, 0.5);

        // 2 possible centers
        var c1 = {
            x: m.x - h * v,
            y: m.y + h * u
        }
        var c2 = {
            x: m.x + h * v,
            y: m.y - h * u
        }


        // get arc midpoints
        var m1 = mfn(p0, p1, c1, r);
        var m2 = mfn(p0, p1, c2, r);


        // convert back to lat / long
        var mo1 = projection.invert([m1.x, m1.y]);
        var mo2 = projection.invert([m2.x, m2.y]);

        return [mo1, mo2]
    }

    return Q31428016;
})();


// your latitude / longitude
var co1 = [-70, -28];
var co2 = [70, 48];

var mo = Q31428016.convert(co1, co2)

// your output
console.log(mo[0]);
console.log(mo[1]);

关于javascript - 计算经纬度坐标的中点,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31428016/

10-13 09:31