Java 如何让android应用程序用多个标记显示最近的位置

Java 如何让android应用程序用多个标记显示最近的位置,java,android,google-maps,google-maps-markers,android-maps-v2,Java,Android,Google Maps,Google Maps Markers,Android Maps V2,我正在尝试做一个应用程序,它显示了5个最近的地方与多个标记从我的当前位置。在其他主题上,我看到了很多例子,但是,没有人解释如何创建带有多个标记的应用程序或显示最近位置的HashMap。请帮我解决它 这是我的主要活动 public class MainActivity extends Activity { private GoogleMap mMap; private ArrayList<MyMarker> mMyMarkersArray = new ArrayList

我正在尝试做一个应用程序,它显示了5个最近的地方与多个标记从我的当前位置。在其他主题上,我看到了很多例子,但是,没有人解释如何创建带有多个标记的应用程序或显示最近位置的HashMap。请帮我解决它

这是我的主要活动

public class MainActivity extends Activity
{
    private GoogleMap mMap;
    private ArrayList<MyMarker> mMyMarkersArray = new ArrayList<MyMarker>();
    private HashMap<Marker, MyMarker> mMarkersHashMap;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mMarkersHashMap = new HashMap<Marker, MyMarker>();

mMyMarkersArray.add(new MyMarker("Restaurant Zaplet", "Telephone:   \n Address: ", "iconZaplet", Double.parseDouble("43.381499"), Double.parseDouble("19.808931")));
mMyMarkersArray.add(new MyMarker("Restaurant Oresac", "Telephone:   \n Address: ","iconOresac", Double.parseDouble("43.796009"), Double.parseDouble("21.745934")));
mMyMarkersArray.add(new MyMarker("Restaurant Obilic","Telephone:  \n    Address: ", "iconObilic", Double.parseDouble("42.547670"), Double.parseDouble("19.660000")));
mMyMarkersArray.add(new MyMarker("Restaurant Dva sesira","Telephone:    \n Address: XII vek", "iconDvaSesira", Double.parseDouble("41.486736"), Double.parseDouble("20.731670")));
mMyMarkersArray.add(new MyMarker("Manastir Lipov Lad", "Telephone:  \n Address: ","iconLipovLad", Double.parseDouble("44.850546"), Double.parseDouble("20.479869")));
mMyMarkersArray.add(new MyMarker("Restaurant Slodes", "Telephone: nepoznato \n Address: ", "iconSlodes", Double.parseDouble("41.503238"), Double.parseDouble("19.791890")));

    setUpMap();

    plotMarkers(mMyMarkersArray);

}

private void plotMarkers(ArrayList<MyMarker> markers)
{
    if(markers.size() > 0)
    {
        for (MyMarker myMarker : markers)
        {

            MarkerOptions markerOption = new MarkerOptions().position(new LatLng(myMarker.getmLatitude(), myMarker.getmLongitude()));
            markerOption.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_restaurant));

            Marker currentMarker = mMap.addMarker(markerOption);
            mMarkersHashMap.put(currentMarker, myMarker);

            mMap.setInfoWindowAdapter(new MarkerInfoWindowAdapter());

        }
    }
}

private int manageMarkerIcon(String markerIcon)
{
    if (markerIcon.equals("iconZaplet"))
        return R.drawable.zaplet;
    else if(markerIcon.equals("iconOresac"))
        return R.drawable.oresac;
    else if(markerIcon.equals("iconObilic"))
        return R.drawable.obilic;
    else if(markerIcon.equals("iconLipovLad"))
        return R.drawable.lipovlad;
    else if(markerIcon.equals("iconSlodes"))
        return R.drawable.slodes;
    else
        return R.drawable.icondefault;
}


private void setUpMap()
{
    if (mMap == null)
    {
        mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();


        if (mMap != null)
        {
            mMap.setMyLocationEnabled(true);

            LocationManager lm = (LocationManager) getSystemService (LOCATION_SERVICE);

            String provider = lm.getBestProvider(new Criteria (), true);

            if (provider == null) {
                onProviderDisabled (provider);
            }

            Location loc = lm.getLastKnownLocation(provider);
            if (loc != null) {
                onLocationChanged (loc);
            }


            mMap.setOnMapLongClickListener(onLongClickMapSettings ());
            mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
            {
                @Override
                public boolean onMarkerClick(com.google.android.gms.maps.model.Marker marker)
                {
                    marker.showInfoWindow();
                    return true;
                }
            });
        }
        else
            Toast.makeText(getApplicationContext(), "Unable to create Maps", Toast.LENGTH_SHORT).show();
    }
}

private OnMapLongClickListener onLongClickMapSettings() {
    // TODO Auto-generated method stub
    return new OnMapLongClickListener () {

        @Override
        public void onMapLongClick(LatLng arg0) {
            // TODO Auto-generated method stub
            Log.i(arg0.toString(), "User long clicked");

        }

    };
}

public void onLocationChanged(Location location) {
    // TODO Auto-generated method stub

    LatLng latlng = new LatLng (location.getLatitude(), location.getLongitude());

    mMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(10));

}


public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub

}


public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub

}


public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub

}

public class MarkerInfoWindowAdapter implements GoogleMap.InfoWindowAdapter
{
    public MarkerInfoWindowAdapter()
    {
    }

    @Override
    public View getInfoWindow(Marker marker)
    {
        return null;
    }


    @SuppressLint("InflateParams") @Override
    public View getInfoContents(Marker marker)
    {
        View v  = getLayoutInflater().inflate(R.layout.info_window_layout, null);

        MyMarker myMarker = mMarkersHashMap.get(marker);

        ImageView markerIcon = (ImageView) v.findViewById(R.id.marker_icon);

        TextView markerLabel = (TextView)v.findViewById(R.id.marker_label);

        TextView anotherLabel = (TextView)v.findViewById(R.id.another_label);

        markerIcon.setImageResource(manageMarkerIcon(myMarker.getmIcon()));

        markerLabel.setText(myMarker.getmLabel());
        anotherLabel.setText(myMarker.getmIstorijat());

        return v;
    }
}

}

很抱歉,我不太明白你的问题所在。似乎您知道如何使用HashMap恢复MyMarker对象的映射标记。您还可以创建所需的所有标记。因为您的问题是创建一个具有HashMap和多个标记的应用程序,所以您似乎已经完成了这项工作。除非你的代码不起作用,但在这种情况下,如果你告诉我们它到底做了什么,那就很有帮助了


我不确定你在问什么,但我相信你有5个标记,你想得到最接近的一个。如果你的问题是如何做到这一点,那么我认为你只需要在每个标记上循环,并计算它们与用户位置的距离,以找到最小的标记

如果你不知道如何计算距离,我通常使用距离定位法。也许这不是最好的代码,但下面是它的样子:

public static double distanceTo(LatLng from, LatLng to) {
    Location locationA = new Location("");
    locationA.setLatitude(from.latitude);
    locationA.setLongitude(from.longitude);
    Location locationB = new Location("");
    locationB.setLatitude(to.latitude);
    locationB.setLongitude(to.longitude);
    return locationA.distanceTo(locationB) / 1000;
}
例如,您可以这样做:

Marker closest = null;
double minDistance;
for(Marker m : mMarkersHashMap.keySet()){
    double distance = distanceTo(currentPos, m.getPosition())
    if(closest == null || minDistance > distance){
        closest = m;
        minDistance = distance;
    }
}
写得很快,还没有测试过,但如果你想对5个最接近的标记进行测试,我认为这是可行的:

Marker[] closest = new Marker[5];
double[] minDistance = new double[5];
for(Marker m : mMarkersHashMap.keySet()){
    double distance = distanceTo(currentPos, m.getPosition())
    for(int i = 4; i >=0; i--){
        if(closest[i] == null || minDistance[i] > distance){
            if(i < 4){
                closest[i+1] = closest[i];
                minDistance[i+1] = minDistance[i];
            }
            closest[i] = m;
            minDistance[i] = distance;
        } else {
            break;
        }
    }
}
Marker[]最近的=新标记[5];
double[]minDistance=新的double[5];
对于(标记m:mMarkersHashMap.keySet()){
双距离=距离(currentPos,m.getPosition())
对于(int i=4;i>=0;i--){
if(最近的[i]==null | |距离[i]>距离){
if(i<4){
最近的[i+1]=最近的[i];
心灵距离[i+1]=心灵距离[i];
}
最近[i]=m;
距离[i]=距离;
}否则{
打破
}
}
}

代码到底出了什么问题?代码是正确的,但我不知道如何设置以显示当前位置的最近位置我看不到您的requestLocationUpdates(…),您可以使用lm.getLastKnownLocation(provider)手动调用onLocationChanged(…)。。。它有用吗?如果您没有请求更新,我认为getLastKnownLocation不应该返回位置。如果使用requestLocationUpdates设置LocationListener,LocationListener的onLocationChanged方法将在LocationUpdates上自动调用。我建议您查看一下我还建议您使用“@Override”注释,因为您似乎希望活动重写LocationListener的方法,但它没有实现此接口。“@Override”将生成一个错误,帮助您查看是否忘记实现此接口。我希望该应用程序显示5个最近的标记,因为我将扩展HashMap上的标记数。我如何应用calucalte的方法在我的示例中显示的距离?我如何在我的应用程序中应用distanceTo?除了我必须在每个标记上循环外,还有其他方法吗?“如果你的问题是如何循环,那么我认为你只需要在每个标记上循环,并计算它们与用户位置的距离,以找到最小的标记。”我同意,没有其他方法可以找到离给定位置最近的标记。我尝试测试你的代码,但我在行double distance=distanceTo(currentPos,m.getPosition())中有错误,因为currentPos不能解析为变量。我应该做什么?currentPos是用户的当前位置。您可以从getlastknownlocation获取它,也可以使用RequestLocationUpdate将它发送到locationlistener集
Marker[] closest = new Marker[5];
double[] minDistance = new double[5];
for(Marker m : mMarkersHashMap.keySet()){
    double distance = distanceTo(currentPos, m.getPosition())
    for(int i = 4; i >=0; i--){
        if(closest[i] == null || minDistance[i] > distance){
            if(i < 4){
                closest[i+1] = closest[i];
                minDistance[i+1] = minDistance[i];
            }
            closest[i] = m;
            minDistance[i] = distance;
        } else {
            break;
        }
    }
}