Calculate the mid point of latitude and longitude co-ordinates

后端 未结 4 1505
我寻月下人不归
我寻月下人不归 2021-01-13 12:41

Does anyone know the best way to go about getting the mid-point of a pair of latitude and longitude points?

I mm using d3.js to draw points on a map and need to draw

4条回答
  •  隐瞒了意图╮
    2021-01-13 12:49

    Apologies for the long script - it just seemed fun to draw stuff :-). I've marked off sections that are not required

    // 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/


    enter image description here


    And here's just the relevant portion (most of it is just copy-pasta from the beginning of this answer)

    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]);
    

提交回复
热议问题