【问题标题】:How to locate the nearest marker to a user?如何找到离用户最近的标记?
【发布时间】:2020-09-25 14:38:41
【问题描述】:

我对 android 开发很陌生,我想知道是否可以使用折线和谷歌方向 api 找到离用户最近的标记并知道哪个标记最接近用户。标记的位置取自我已解析为列表数组的数据库,然后我使用该列表将标记放置在地图上。我试图从其他问题中寻求帮助,但它们似乎不适合我的项目。

如果我可以找到离用户最近的标记,我该怎么做?如果没有,我可以使用其他方法吗??

这是我的主要活动代码:

package com.example.defiblocator;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;



public class MainActivity extends AppCompatActivity implements OnMapReadyCallback,
        LocationListener,GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener{

    public static TextView data;
    public static String location;
    GoogleMap mapAPI;
    SupportMapFragment mapFragment;
    Location mLastLocation;
    Marker mCurrLocationMarker;
    GoogleApiClient mGoogleApiClient;
    LocationRequest mLocationRequest;
    String delimiter = ",";
    List<String> full = new ArrayList<>();
    List<String> size = new ArrayList<>();
    private ArrayList<LatLng> markerCoords = new ArrayList<LatLng>();
    String info;
    String name;
    Double lat;
    Double lng;
    Button emergency;
    LatLng mark;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.mapAPI);
        mapFragment.getMapAsync(this);

        data = findViewById(R.id.fetchdata);
        new fetchData(new CallbackClass()).execute();

        emergency = findViewById(R.id.button);
        emergency.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {

            }
        });

    }



    @Override
    public void onMapReady(GoogleMap googleMap) {

        mapAPI = googleMap;
        mapAPI.getUiSettings().setZoomControlsEnabled(true);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                buildGoogleApiClient();
                mapAPI.setMyLocationEnabled(true);
                //mapAPI.setOnMyLocationChangeListener(this);
            }
        } else {
            buildGoogleApiClient();
            mapAPI.setMyLocationEnabled(true);
        }

    }

    protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API).build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle bundle) {

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(1000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }

    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onLocationChanged(Location location) {

        /*mLastLocation = location;
        if (mCurrLocationMarker != null) {
            mCurrLocationMarker.remove();
        }*/
        //Place current location marker
        LatLng patient = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(patient);
        markerOptions.title("Patient");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
        mCurrLocationMarker = mapAPI.addMarker(markerOptions);

        //move map camera
        mapAPI.animateCamera(CameraUpdateFactory.zoomTo(11));
        mapAPI.moveCamera(CameraUpdateFactory.newLatLng(patient));

        //stop location updates
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }

    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    public class CallbackClass implements CallbackInterface {

        @Override
        public void onSuccess(String callbackData) {
            info = callbackData;
            full = Arrays.asList(info.split(delimiter));
            size = Arrays.asList(info.split(delimiter));

            Integer x = 0;
            while(x != size.size()){

                name = full.get(x);
                x += 1;
                lat = Double.valueOf(full.get(x));
                x += 1;
                lng = Double.valueOf(full.get(x));
                x += 1;
                LatLng pos = new LatLng(lat, lng);
                mapAPI.addMarker(new MarkerOptions().position(pos).title(name));

                mark = new LatLng(lat,lng);
                markerCoords.add(mark);

            }
        }

        @Override
        public void onFailure() {

        }
    }

}

这是从数据库中解析 JSON 的代码,任何帮助将不胜感激。

package com.example.defiblocator;

import android.app.Application;
import android.os.AsyncTask;
import android.widget.TextView;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;


public class fetchData extends AsyncTask <Void,Void,Void>{

    CallbackInterface callbackInterface;
    String data = "";
    String json_url;
    String singleParsed = "";
    public String dataParsed = "";
    String sent;

    public fetchData(CallbackInterface callbackInterface) {
        this.callbackInterface = callbackInterface;
    }


    public Integer x = 0;
    @Override
    protected void onPreExecute(){
        json_url = "http://defiblocator.ml/json_get_data.php";
        dataParsed = "";
    }
    @Override
    protected Void doInBackground(Void... voids) {


        try {
            URL url = new URL(json_url);
            HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
            InputStream inputStream = httpURLConnection.getInputStream();
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
            String line = "";
            while(line != null){
                line = bufferedReader.readLine();
                data = data + line;
            }

            JSONArray JA = new JSONArray(data);
            for(int i =0 ; i <JA.length(); i++){
                JSONObject JO = (JSONObject) JA.get(i);
                singleParsed = JO.get("name") + "," + JO.get("lat") + "," +JO.get("lng") + "," ;
                dataParsed = dataParsed + singleParsed ;
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException | JSONException e){
            e.printStackTrace();
        }

        return null;
    }



    @Override
    protected void onPostExecute(Void aVoid) {

        MainActivity.data.setText(dataParsed);
        callbackInterface.onSuccess(dataParsed);

    }



}

【问题讨论】:

    标签: java android google-maps


    【解决方案1】:

    您可以使用一个简单的距离公式来存档:

    private Double distance(Double lat1, Double lon1, Double lat2, Double lon2) {
      return Math.sqrt (Math.pow((lat1 - lat2), 2) - Math.pow((lon1 - lon2), 2));
    }
    
    
    // The user Location
    currentLat = xxxx;
    currentLon = xxxx;
    
    if ((markerCoords != null) && (markerCoords.size() > 0)) {
      LatLng near = markerCoords.get(0);
      for (int x = 1; x < markerCoords.size(); x++) {
        Double lat = markerCoords.get(x).latitude;
        Double lon = markerCoords.get(x).longitude;
    
        Double currentMarkerdistance = distance(
          currentLat, 
          currentLon, 
          markerCoords.get(x).latitude,
          markerCoords.get(x).longitude);
    
        Double nearMarkerdistance = distance(
          currentLat, 
          currentLon, 
          near.latitude,
          near.longitude);
    
        if (currentMarkerdistance < nearMarkerdistance) {
          near = markerCoords.get(x);
        }
      }
    }
    
    // After this process the near variable will hold the near marker 
    
    
    

    【讨论】:

    • 当我试图实现你的想法时,我不断收到 .getPosition() 的错误我做错了什么??
    • 现在我看到 markerCoords 是一个 LatLng 的 ArrayList。我编辑了我的答案
    猜你喜欢
    • 2013-07-06
    • 2017-02-22
    • 2014-09-07
    • 2016-02-17
    • 1970-01-01
    • 2018-02-06
    • 2016-06-09
    • 1970-01-01
    • 2013-09-10
    相关资源
    最近更新 更多