java – 如何在两个其他点之间找到地理点

对于我的应用程序,我必须在谷歌地图上找到一个点的位置,只知道它位于其他2个点和捕获坐标的时间(以毫秒为单位)之间.

在我的代码中,假定A和B为给定点,X为要查找的点,I:

>计算A和B之间的距离
>基于时间我发现了从A到B的速度(以微米/毫秒为单位)
>我找到了从A点到X点的距离(使用时间和速度)
>使用类似的三角形规则,我从点A计算点X的纬度和经度

此工作流程会在地图上显示错误,因此,X标记通常不在A和B标记之间.

我怎样才能使它更好用?它是地球球形的一个问题吗?

谢谢你们.

这是代码

    int ax = oldPoint.getLatitude();
    int ay = oldPoint.getLongitude();

    int bx = currentPoint.getLatitude();
    int by = currentPoint.getLongitude();

    long at = oldPoint.getDataRilevamento(); //get time first point
    long bt = currentPoint.getDataRilevamento(); // get time second point
    long xt = x.getDate(); // time of point to find

    int c1 = bx-ax;
    int c2 = by-ay;
    double hyp =  Math.sqrt(Math.pow(c1, 2) + Math.pow(c2, 2));

    double vel = hyp / (bt-at);

    double pos = vel*(xt - at);

    int posx = (int)((pos*c1)/hyp);
    int posy = (int)((pos*c2)/hyp);

    x.setLatitude(ax+posx); //set the latitude of X
    x.setLongitude(ay+posy); // set the longitude of X

解决方法:

您可以通过以下步骤解决您的问题.

>计算A点和B点的距离(使用Haversine formula,这在这里足够好,或者更复杂的Vincenty formula).要使用
公式正确,Android的microdegrees,这就是getLatitude
和getLongitude返回,必须转换为弧度,
使用这样的公式:

 double radians = Math.toradians((double)microdegrees/1000000);

>从A点和B点计算轴承(方向)(使用公式
在同一页上).这与毕达哥拉斯公式不同,因为
地球是圆的,不是平的.
>然后你可以选择一个新的距离并计算给定的X点
A点和上一步中找到的轴承(参见同一页面上的“目标点给定距离和起点承载”或Vincenty’s
direct formula
).
>使用以下公式将生成点的弧度转换为微度:

 int microdegrees = (int)(Math.todegrees(radians)*1000000);

总而言之,我们有以下功能,我将其置于公共领域:

    public static int[] getIntermediatePoint(
        int startLatMicroDeg,
        int startLonMicroDeg,
        int endLatMicroDeg,
        int endLonMicroDeg,
        double t // How much of the distance to use, from 0 through 1
    ){
        // Convert microdegrees to radians
        double alaTrad=Math.toradians((double)startLatMicroDeg/1000000);
        double alonRad=Math.toradians((double)startLonMicroDeg/1000000);
        double blaTrad=Math.toradians((double)endLatMicroDeg/1000000);
        double blonRad=Math.toradians((double)endLonMicroDeg/1000000);
        // Calculate distance in longitude
        double dlon=blonRad-alonRad;
        // Calculate common variables
        double alaTradSin=Math.sin(alaTrad);
        double blaTradSin=Math.sin(blaTrad);
        double alaTradCos=Math.cos(alaTrad);
        double blaTradCos=Math.cos(blaTrad);
        double dlonCos=Math.cos(dlon);
        // Find distance from A to B
        double distance=Math.acos(alaTradSin*blaTradSin +
                                  alaTradCos*blaTradCos *
                                  dlonCos);
        // Find bearing from A to B
        double bearing=Math.atan2(
            Math.sin(dlon) * blaTradCos,
            alaTradCos*blaTradSin -
            alaTradSin*blaTradCos*dlonCos);
        // Find new point
        double angulardistance=distance*t;
        double angdistSin=Math.sin(angulardistance);
        double angdistCos=Math.cos(angulardistance);
        double xlaTrad = Math.asin( alaTradSin*angdistCos +
                                   alaTradCos*angdistSin*Math.cos(bearing) );
        double xlonRad = alonRad + Math.atan2(
            Math.sin(bearing)*angdistSin*alaTradCos,
            angdistCos-alaTradSin*Math.sin(xlaTrad));
        // Convert radians to microdegrees
        int xlat=(int)Math.round(Math.todegrees(xlaTrad)*1000000);
        int xlon=(int)Math.round(Math.todegrees(xlonRad)*1000000);
        if(xlat>90000000)xlat=90000000;
        if(xlat<-90000000)xlat=-90000000;
        while(xlon>180000000)xlon-=360000000;
        while(xlon<=-180000000)xlon+=360000000;
        return new int[]{xlat,xlon};
    }

以下是它的使用方法

int ax = oldPoint.getLatitude();
int ay = oldPoint.getLongitude();

int bx = currentPoint.getLatitude();
int by = currentPoint.getLongitude();

long at = oldPoint.getDataRilevamento(); //get time first point
long bt = currentPoint.getDataRilevamento(); // get time second point
long xt = x.getDate(); // time of point to find

// Find relative time from point A to point B
double t=(bt==at) ? 0 : ((double)(xt-at))/((double)(bt-at));
// Find new point given the start and end points and the relative time
int[] xpos=getIntermediatePoint(ax,ay,bx,by,t);
x.setLatitude(xpos[0]); //set the latitude of X
x.setLongitude(xpos[1]); // set the longitude of X

相关文章

Android性能优化——之控件的优化 前面讲了图像的优化,接下...
前言 上一篇已经讲了如何实现textView中粗字体效果,里面主要...
最近项目重构,涉及到了数据库和文件下载,发现GreenDao这个...
WebView加载页面的两种方式 一、加载网络页面 加载网络页面,...
给APP全局设置字体主要分为两个方面来介绍 一、给原生界面设...
前言 最近UI大牛出了一版新的效果图,按照IOS的效果做的,页...