首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >当我的当前位置在2个或更多的圆圈内时,如何在谷歌地图android中找到圆圈外的最短路径?

当我的当前位置在2个或更多的圆圈内时,如何在谷歌地图android中找到圆圈外的最短路径?
EN

Stack Overflow用户
提问于 2017-05-04 13:15:26
回答 1查看 571关注 0票数 2

如果蓝点是当前位置,如何获得圆圈外最近位置的方向?

1[

1

如何在半径为2000m的范围内只显示当前位置的标记?我已经在数据库中存储了地图lanslide,它在应用程序启动时显示,它需要7-9秒来加载这些标记。现在我需要只显示在当前位置附近,以便应用程序顺利进行。

这些是lanslide的映射点

我正在做我的最后一个项目,我有一个fEature,这真的很难。

我在我的android项目中,在android上制作了一个关于lanslide灾难的警告应用程序,我绘制了lanslide位置的地图,收集了大约150对纬度和经度,并将其放入数据库中。

我假设如果用户在圆圈内,他们在lanslide位置,他们是不安全的

红区半径距圆心2公里。橙色带半径距圆心1公里。黄色区半径距圆心500米

当应用程序启动时,地图会显示出来,并将相机动画显示到我当前的位置。然后应用程序会告诉用户他们是否安全。如果用户在圈外,则用户是安全的。但是,如果当前位置在圆内,那么用户就不安全。当用户不安全时,应用程序会向圆圈外的最短路径指示方向。

我的应用程序几乎完成了,除了最后一个功能,我不知道如何弄清楚它,

应用程序如何给出圆圈外的最短路径的方向?

不幸的是,如果当前位置在3或更多的圆圈内,应用程序如何为用户提供最短的外圈方向?我能用什么谷歌的库来解决这个问题呢?

如何在许多圈子之外获得方向?请帮帮我。

enter image description here

这是我的代码:

公共类MenuMaps扩展片段实现OnMapReadyCallback {私有静态MenuMaps实例= null;

代码语言:javascript
运行
复制
private SupportMapFragment sMapFragment;
private MapView mMapView;
SupportMapFragment mapFragment;
private GoogleMap mMap;
private String[] id, desa, status_des;
  boolean markerD[];
private Double latitude, longitude;
private Circle mCircle;
private Marker mMarker;
LatLng lokasisekarang;


boolean mapReady = false;

private GoogleApiClient client;

private GoogleApiClient client2;

public static MenuMaps getInstance() {
    if (instance == null) {
        instance = new MenuMaps();
        Log.d( "MenuMaps", "getInstance");
    }
    return instance;
}



@Nullable
@Override

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)


{
    Log.d("MenuMaps", "OnCreateView");
    View inflatedView = inflater.inflate(R.layout.menu_maps, container, false);

    MapsInitializer.initialize(getActivity());

    mMapView = (MapView) inflatedView.findViewById(R.id.map);
    mMapView.onCreate(savedInstanceState);

    mMapView.getMapAsync(this);


        Button btnMap = (Button) inflatedView.findViewById(R.id.btnMap);
    btnMap.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mapReady)
                mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);

        }
    }) ;


    Button btnSatellite = (Button) inflatedView.findViewById(R.id.btnSatellite);
    btnSatellite.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (mapReady)
                mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
        }
    });

    Button btnHybrid = (Button) inflatedView.findViewById(R.id.btnHybrid);
    btnHybrid.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if(mapReady)
                mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        }
    });

  return inflatedView;
}

@Override

public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    getActivity().setTitle("Menu Maps");
}


@Override
public void onStart() {
    super.onStart();
}

@Override
public void onStop() {
    super.onStop();
}

@Override
public void onResume() {
    mMapView.onResume();
    super.onResume();
}
@Override
public void onPause() {
    super.onPause();
    mMapView.onPause();
}
@Override
public void onDestroy() {
    super.onDestroy();
    mMapView.onDestroy();
}
@Override
public void onLowMemory() {
    super.onLowMemory();
    mMapView.onLowMemory();
}

@Override
public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);


}


public void getLokasi() {
    Log.d("desaStatus", "getLokasi");

    String url = "http://dharuelfshop.com/skripsi/desaStatus.php/";
    StringRequest request = new StringRequest(url, new Response.Listener<String>() {
        @Override
        public void onResponse(String response) {
            Log.d("desaStatus", response);
            Gson gson = new Gson();


            try {
                JSONObject objinduk = new JSONObject(response);
                List<DesaStatus> listDesaStatus = gson.fromJson(objinduk.getString("desaStatus"), new TypeToken<List<DesaStatus>>() {
                }.getType());

                Circle circleTerdekat = null;
                Float distanceTerdekat = null;



                for (DesaStatus desaStatus : listDesaStatus
                        ) {
                    Log.d("desaStatus", desaStatus.toString());

                    LatLng center = new LatLng(desaStatus.lat_bcn,
                            desaStatus.long_bcn);

                    MarkerOptions markerOptions = new MarkerOptions()
                            .position(center)
                            .title("Desa : " + desaStatus.nama_des)
                            .snippet("Status : " + desaStatus.jenis_status)
                            .icon(BitmapDescriptorFactory
                                    .defaultMarker(desaStatus.kode_warna));
                    mMarker = mMap.addMarker(markerOptions);

                    CircleOptions CircleOptions =  new CircleOptions()
                            .center(center)
                            .radius(desaStatus.radius)//in meters
                            .strokeColor(Color.parseColor(desaStatus.warna_radius))
                            .strokeWidth(2)
                            .fillColor(Color.parseColor(desaStatus.warna_radius));
                    mCircle = mMap.addCircle(CircleOptions);

                    //hitung distance dan Status circle
                    float[] distance = new float[2];

                    Location.distanceBetween( lokasisekarang.latitude, lokasisekarang.longitude,
                            mCircle.getCenter().latitude, mCircle.getCenter().longitude, distance);

                    if (circleTerdekat == null) {
                        circleTerdekat = mCircle;
                        distanceTerdekat = distance[0];

                    } else {
                        if (distance[0] < distanceTerdekat ) {
                            distanceTerdekat = distance[0];
                            circleTerdekat = mCircle;
                        }
                    }

                }
                Log.d("circleTerdekat", "center: " + circleTerdekat.getCenter().latitude + " " + circleTerdekat.getCenter().longitude );

                if( distanceTerdekat > circleTerdekat.getRadius() ){
                    Toast.makeText(getContext(), "You are safe, distance from center: " + distanceTerdekat + " radius: " + circleTerdekat.getRadius(), Toast.LENGTH_LONG).show();
                } else {
                    Toast.makeText(getContext(), "You are not safe, distance from center: " + distanceTerdekat + " radius: " + circleTerdekat.getRadius() , Toast.LENGTH_LONG).show();
                }

            }  catch (JSONException error) {
                Log.d("desaStatusError", error.toString());
            }
          }
        }
    }, new Response.ErrorListener() {


        @Override
        public void onErrorResponse(VolleyError error) {

            AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
            builder.setTitle("Error woy");
            //Message
            builder.setMessage("Error " + error); //+ error diganti sama (VolleyError error)
            //Message

            //builder.setIcon()
            builder.setPositiveButton("Refreshh", new DialogInterface.OnClickListener() {
                @Override //O nya huruf gede
                public void onClick(DialogInterface dialog, int which) {
                    getLokasi();
                }
            });
            AlertDialog alert = builder.create();
            alert.show();
        }
    });

    // menambah request ke request queue
    VolleyRequest.getInstance().addToRequestQueue(request);
}

public void getCurrentLocation() {
    GpsTracker gps = new GpsTracker(getActivity());
    if (gps.canGetLocation()) { // gps enabled
        //Getting longitude and latitude
        latitude = gps.getLatitude();
        longitude = gps.getLongitude();

        lokasisekarang = new LatLng(latitude, longitude);
        drawMarkerWithCircle(lokasisekarang);

        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(lokasisekarang, 14f));


        // \n is for new line
        //Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
    }

    else {
        // can't get location
        // GPS or Network is not enabled
        // Ask user to enable GPS/network in settings
        gps.showSettingsAlert();
        //gps.stopUsingGPS();
    }
}

private void drawMarkerWithCircle(LatLng lokasisekarang) {
    MarkerOptions markerOptions = new MarkerOptions()
            .position(lokasisekarang)
            .title("You are here")
            .snippet("here")
            .icon(BitmapDescriptorFactory
                    .defaultMarker(HUE_BLUE));
    mMarker = mMap.addMarker(markerOptions);

    CircleOptions circleOptions = new CircleOptions()
            .center(lokasisekarang)
            .radius(2000)
            .strokeWidth(2)
            .strokeColor(Color.BLUE)
            .fillColor(Color.parseColor("#500084d3"));

    mMap.addCircle(circleOptions);
}

@Override
    public void onMapReady(GoogleMap googleMap) {
    mapReady = true;

    mMap = googleMap;
    getCurrentLocation();
    getLokasi();
    if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }

    mMap.setMyLocationEnabled(true);
    mMap.getUiSettings().setMyLocationButtonEnabled(true); // buat enable button location

}}
EN

回答 1

Stack Overflow用户

发布于 2017-05-04 14:10:04

为了显示方向,您需要两个点,即起点和目的地。在本例中,原点将是您用户的位置。

查找目标点:

1)目前您正在存储这些圆形区域的中心及其半径(500米,1公里等)。除此之外,你还可以很容易地计算出每个圆沿着4个方向(比如N,S,E,W)的4个“安全”点,并将它们存储起来。

2)这些点将你的圆分成4个象限。现在,您需要做的就是找到用户当前所在的圆的哪个象限,比较构成象限的点之间的距离,然后选择两个点中较低的一个作为您的目的地。

3)使用谷歌地图Directions API显示方向。

如果你想提高算法的精度,你所需要做的就是增加方向的数量,这将有效地将你的圆圈划分为更小的部分,并且目的地将更加优化。

这里的'4‘只是一个任意的数字。您可以根据您选择的安全点的数量使用不同的数字,这将决定算法的准确性

编辑:处理多个圆的相交也很容易。然后,您需要做的不是计算1个圆的最短圆,而是计算点所在的所有圆,然后找到最小距离

算法:

1)对于每个圆,选择'n‘个安全点。这些'n‘点将在圆中形成n - 1扇区。

2)获取用户的当前位置(例如A),并找到包含该点的所有圆。

3)对于pt A所在的每个圆,计算它所在的扇区。假设它位于由点X_iY_i形成的扇区上。计算距离AX_iAY_i

4)选择所有距离的最小值AX_iAY_i并显示这些点的导航说明

如果标记在视觉上看起来彼此很接近,这并不重要。你不会在视觉上找到计算设备要做的方向。无论如何,经纬度值具有非常高的精度。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43774395

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档