Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/230.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 映射,测试当前位置是否在多段线上或附近_Android_Google Maps_Maps - Fatal编程技术网

Android 映射,测试当前位置是否在多段线上或附近

Android 映射,测试当前位置是否在多段线上或附近,android,google-maps,maps,Android,Google Maps,Maps,我正在使用google directions api为管线绘制多段线。有没有人有过检查当前位置是否在多段线上/附近的例子?试图确定用户当前位置是否在该线路的x米范围内,如果不是,我将发出新请求并重新绘制新路线 干杯 这是我的解决方案:只需将我创建的bdccGeoDistanceAlgorithm类添加到您的项目中,并使用bdccGeoDistanceCheckWithRadius方法检查您的当前位置是否位于多段线上或附近(多段线等于一系列点) 您还可以通过该方法获得距离 类bdccGeoDist

我正在使用google directions api为管线绘制多段线。有没有人有过检查当前位置是否在多段线上/附近的例子?试图确定用户当前位置是否在该线路的x米范围内,如果不是,我将发出新请求并重新绘制新路线


干杯

这是我的解决方案:只需将我创建的
bdccGeoDistanceAlgorithm
类添加到您的项目中,并使用
bdccGeoDistanceCheckWithRadius
方法检查您的当前位置是否位于多段线上或附近(多段线等于一系列点) 您还可以通过该方法获得距离

bdccGeoDistanceAlgorithm

import com.google.android.gms.maps.model.LatLng;

import java.util.List;

public class bdccGeoDistanceAlgorithm {

// distance in meters from GLatLng point to GPolyline or GPolygon poly
public static boolean bdccGeoDistanceCheckWithRadius(List<LatLng> poly, LatLng point, int radius)
{
    int i;
    bdccGeo p = new bdccGeo(point.latitude,point.longitude);

    for(i=0; i < (poly.size()-1) ; i++)
    {
        LatLng p1 = poly.get(i);
        bdccGeo l1 = new bdccGeo(p1.latitude,p1.longitude);

        LatLng p2 = poly.get(i+1);
        bdccGeo l2 = new bdccGeo(p2.latitude,p2.longitude);

        double distance = p.function_distanceToLineSegMtrs(l1, l2);

        if(distance < radius)
            return true;
    }
    return false;
}


// object

public static class bdccGeo
{
    public double lat;
    public double lng;

    public double x;
    public double y;
    public double z;


    public bdccGeo(double lat, double lon) {
        this.lat = lat;
        this.lng = lng;

        double theta = (lon * Math.PI / 180.0);
        double rlat = function_bdccGeoGeocentricLatitude(lat * Math.PI / 180.0);
        double c = Math.cos(rlat);
        this.x = c * Math.cos(theta);
        this.y = c * Math.sin(theta);
        this.z = Math.sin(rlat);
    }

    //returns in meters the minimum of the perpendicular distance of this point from the line segment geo1-geo2
    //and the distance from this point to the line segment ends in geo1 and geo2
    public double function_distanceToLineSegMtrs(bdccGeo geo1,bdccGeo geo2)
    {

        //point on unit sphere above origin and normal to plane of geo1,geo2
        //could be either side of the plane
        bdccGeo p2 = geo1.function_crossNormalize(geo2);

        // intersection of GC normal to geo1/geo2 passing through p with GC geo1/geo2
        bdccGeo ip = function_bdccGeoGetIntersection(geo1,geo2,this,p2);

        //need to check that ip or its antipode is between p1 and p2
        double d = geo1.function_distance(geo2);
        double d1p = geo1.function_distance(ip);
        double d2p = geo2.function_distance(ip);
        //window.status = d + ", " + d1p + ", " + d2p;
        if ((d >= d1p) && (d >= d2p))
            return function_bdccGeoRadiansToMeters(this.function_distance(ip));
        else
        {
            ip = ip.function_antipode();
            d1p = geo1.function_distance(ip);
            d2p = geo2.function_distance(ip);
        }
        if ((d >= d1p) && (d >= d2p))
            return function_bdccGeoRadiansToMeters(this.function_distance(ip));
        else
            return function_bdccGeoRadiansToMeters(Math.min(geo1.function_distance(this),geo2.function_distance(this)));
    }

    // More Maths
    public bdccGeo function_crossNormalize(bdccGeo b)
    {
        double x = (this.y * b.z) - (this.z * b.y);
        double y = (this.z * b.x) - (this.x * b.z);
        double z = (this.x * b.y) - (this.y * b.x);
        double L = Math.sqrt((x * x) + (y * y) + (z * z));
        bdccGeo r = new bdccGeo(0,0);
        r.x = x / L;
        r.y = y / L;
        r.z = z / L;

        return r;
    }

    // Returns the two antipodal points of intersection of two great
    // circles defined by the arcs geo1 to geo2 and
    // geo3 to geo4. Returns a point as a Geo, use .antipode to get the other point
    public bdccGeo function_bdccGeoGetIntersection(bdccGeo geo1,bdccGeo  geo2, bdccGeo geo3,bdccGeo geo4)
    {
        bdccGeo geoCross1 = geo1.function_crossNormalize(geo2);
        bdccGeo geoCross2 = geo3.function_crossNormalize(geo4);
        return geoCross1.function_crossNormalize(geoCross2);
    }

    public double function_distance(bdccGeo v2)
    {
        return Math.atan2(v2.function_crossLength(this), v2.function_dot(this));
    }

    //More Maths
    public double function_crossLength(bdccGeo b)
    {
        double x = (this.y * b.z) - (this.z * b.y);
        double y = (this.z * b.x) - (this.x * b.z);
        double z = (this.x * b.y) - (this.y * b.x);
        return Math.sqrt((x * x) + (y * y) + (z * z));
    }

    //Maths
    public double function_dot(bdccGeo b)
    {
        return ((this.x * b.x) + (this.y * b.y) + (this.z * b.z));
    }

    //from Radians to Meters
    public double function_bdccGeoRadiansToMeters(double rad)
    {
        return rad * 6378137.0; // WGS84 Equatorial Radius in Meters
    }

    // point on opposite side of the world to this point
    public bdccGeo function_antipode()
    {
        return this.function_scale(-1.0);
    }

    //More Maths
    public bdccGeo function_scale(double s)
    {
        bdccGeo r = new bdccGeo(0,0);
        r.x = this.x * s;
        r.y = this.y * s;
        r.z = this.z * s;
        return r;
    }

    // Convert from geographic to geocentric latitude (radians).
    public double function_bdccGeoGeocentricLatitude(double geographicLatitude)
    {
        double flattening = 1.0 / 298.257223563;//WGS84
        double f = (1.0 - flattening) * (1.0 - flattening);
        return Math.atan((Math.tan(geographicLatitude) * f));
    }
}
import com.google.android.gms.maps.model.LatLng;
导入java.util.List;
公共类BDCCGeodistance算法{
//从玻璃点到GPolyline或GPolygon多边形的距离(米)
公共静态布尔bdccGeoDistanceCheckWithRadius(列表多边形、LatLng点、整数半径)
{
int i;
bdccGeo p=新的bdccGeo(点、纬度、点、经度);
对于(i=0;i<(poly.size()-1);i++)
{
LatLng p1=多边形get(i);
bdccGeo l1=新的bdccGeo(p1.纬度,p1.经度);
LatLng p2=多边形get(i+1);
bdccGeo l2=新的bdccGeo(p2.纬度,p2.经度);
双倍距离=p.函数与直线段的距离(l1,l2);
if(距离<半径)
返回true;
}
返回false;
}
//反对
公共静态类bdccGeo
{
公共双lat;
公共双液化天然气;
公共双x;
公共双y;
公共双z;
公共bdccGeo(双横向、双纵向){
this.lat=lat;
这是液化天然气=液化天然气;
双θ=(lon*Math.PI/180.0);
双rlat=函数(lat*Math.PI/180.0);
双c=数学cos(rlat);
x=c*Math.cos(θ);
y=c*Math.sin(θ);
this.z=Math.sin(rlat);
}
//返回该点与线段geo1-geo2之间的最小垂直距离(以米为单位)
//从该点到线段的距离以geo1和geo2结束
公共双功能线路段距离(bdccGeo geo1、bdccGeo geo2)
{
//位于原点上方且垂直于geo1、geo2平面的单位球体上的点
//可能是飞机的两边
bdccGeo p2=geo1.函数_交叉规范化(geo2);
//穿过p的GC法线到geo1/geo2与GC geo1/geo2的交点
bdccGeo ip=函数_BDCCGEOGETCROSITION(geo1,geo2,this,p2);
//需要检查ip或其对极是否在p1和p2之间
双d=geo1.函数距离(geo2);
双d1p=geo1.功能距离(ip);
双d2p=geo2。功能距离(ip);
//window.status=d+”,“+d1p+”,“+d2p;
如果((d>=d1p)和&(d>=d2p))
返回函数(此函数为距离(ip));
其他的
{
ip=ip.function_antipode();
d1p=geo1.功能距离(ip);
d2p=geo2.功能距离(ip);
}
如果((d>=d1p)和&(d>=d2p))
返回函数(此函数为距离(ip));
其他的
返回函数(数学最小值(geo1.函数距离(this),geo2.函数距离(this));
}
//更多的数学
公共bdccGeo功能交叉规范化(bdccGeo b)
{
双x=(this.y*b.z)-(this.z*b.y);
双y=(this.z*b.x)-(this.x*b.z);
双z=(this.x*b.y)-(this.y*b.x);
double L=Math.sqrt((x*x)+(y*y)+(z*z));
bdccGeo r=新bdccGeo(0,0);
r、 x=x/L;
r、 y=y/L;
r、 z=z/L;
返回r;
}
//返回两个大图的两个对交点
//由圆弧geo1到geo2定义的圆,以及
//geo3到geo4。返回一个点作为Geo,使用.antipode获取另一个点
公共bdccGeo职能部门与BDCCGEOGETCRIPTION(bdccGeo geo1、bdccGeo geo2、bdccGeo geo3、bdccGeo geo4)
{
bdccGeo geoCross1=geo1.函数_交叉规范化(geo2);
bdccGeo geoCross2=geo3.函数交叉规范化(geo4);
返回geoCross1.函数_crossNormalize(geoCross2);
}
公共双功能距离(bdccGeo v2)
{
返回Math.atan2(v2.function_crossLength(this),v2.function_dot(this));
}
//更多的数学
公共双功能交叉长度(bdccGeo b)
{
双x=(this.y*b.z)-(this.z*b.y);
双y=(this.z*b.x)-(this.x*b.z);
双z=(this.x*b.y)-(this.y*b.x);
返回Math.sqrt((x*x)+(y*y)+(z*z));
}
//数学
公共双功能网点(bdccGeo b)
{
返回((this.x*b.x)+(this.y*b.y)+(this.z*b.z));
}
//从弧度到米
公共双功能(双弧度)
{
返回rad*6378137.0;//WGS84赤道半径(米)
}
//在世界的另一边指向这一点
公共bdccGeo函数_对极()
{
返回此。函数的刻度(-1.0);
}
//更多的数学
公共bdccGeo功能(双s)
{
bdccGeo r=新bdccGeo(0,0);
r、 x=这个.x*s;
r、 y=这个。y*s;
r、 z=这个。z*s;
返回r;
}
//从地理纬度转换为地心纬度(弧度)。
公共双功能地理中心(双地理中心)
{
双展平=1.0/298.257223563;//WGS84
双f=(1.0-展平)*(1.0-展平);
返回Math.atan((Math.tan(地理位置)*f));
}
}

}

这可能会有帮助。对该线程的响应将帮助您以何种格式获取信息。?以米、半径、厘米或什么为单位。?以米为单位的距离。我把它写在上面的评论行