在GoogleMaps中为不同城市选择正确的缩放级别

时间:2017-06-24 10:37:10

标签: android google-maps google-maps-android-api-2

我有一个实现OnMapReadyCallback的活动来显示一些标记。 在打开地图之前,我提供了一个目标城市,我想在地图上看得更近,基本上可以打电话:

 LatLng currentCity = new LatLng(cityLat,cityLng)
 CameraUpdate location = CameraUpdateFactory.newLatLngZoom(currentCity,13);
 googleMap.animateCamera(location);

这里的主要问题是缩放级别只是一个任意数字,适用于某些城市而不适用于其他城市(太放大,放大不够)。 我想要达到的目的是根据城市动态确定缩放级别,方法与谷歌地图相同。

我知道城市的ViewPort越大,缩放需要的越小,但我找不到一种方法来获取给定城市的ViewPort,然后相应地改变缩放级别

编辑:我正在考虑使用Geocoder使用城市的纬度和经度获取地址列表

List<Address> addresses =  mGeocoder.getFromLocation(Lat,Lon,maxLimit);

然后遍历此列表以查找该城市可用的最外层地址,以便构建一个LatLngBounds以通过setLatLngBoundsForCameraTarget()方法。 这种方法的主要问题是,再一次,“maxLimit”是任意的,对于一个大城市来说需要相当大,最终会返回一个非常大的列表

1 个答案:

答案 0 :(得分:1)

您可以从地理编码API reverse geocoding响应中检索城市的视口。

您应该执行HTTP请求以从您的活动中检索城市视图端口。收到回复后,您可以构建LatLngBounds实例并相应地移动相机。

从坐标获取城市的示例反向地理编码请求如下 https://maps.googleapis.com/maps/api/geocode/json?latlng=47.376887%2C8.541694&result_type=locality&key=YOUR_API_KEY

我为Map活动写了一个小例子,它从intent接收lat和lng,使用Volley库执行反向地理编码HTTP请求,并移动摄像头以显示城市视图端口。

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private float lat;
    private float lng;
    private String name;
    private RequestQueue mRequestQueue;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent i = getIntent();
        this.lat = i.getFloatExtra("lat", 0);
        this.lng = i.getFloatExtra("lng", 0);
        this.name = i.getStringExtra("name");

        mRequestQueue = Volley.newRequestQueue(this);

        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }

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

        // Add a marker in Sydney and move the camera
        LatLng pos = new LatLng(this.lat, this.lng);
        mMap.addMarker(new MarkerOptions().position(pos).title(this.name));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(pos));

        this.fetchReverseGeocodeJson();
    }

    private void fetchReverseGeocodeJson() {
        // Pass second argument as "null" for GET requests
        JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET,
               "https://maps.googleapis.com/maps/api/geocode/json?latlng=" + this.lat + "%2C" + this.lng + "&result_type=locality&key=AIzaSyBrPt88vvoPDDn_imh-RzCXl5Ha2F2LYig",
                null,
                new Response.Listener<JSONObject>() {
                    @Override
                    public void onResponse(JSONObject response) {
                        try {
                            String status = response.getString("status");
                            if (status.equals("OK")) {
                                JSONArray results = response.getJSONArray("results");
                                JSONObject item = results.getJSONObject(0);
                                JSONObject geom = item.getJSONObject("geometry");
                                JSONObject bounds = geom.getJSONObject("viewport");
                                JSONObject ne = bounds.getJSONObject("northeast");
                                JSONObject sw = bounds.getJSONObject("southwest");

                                LatLngBounds mapbounds = new LatLngBounds(new LatLng(sw.getDouble("lat"),sw.getDouble("lng")),
                                        new LatLng(ne.getDouble("lat"), ne.getDouble("lng")));

                                mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mapbounds, 0));
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                },
                new Response.ErrorListener() {
                    @Override
                    public void onErrorResponse(VolleyError error) {
                        VolleyLog.e("Error: ", error.getMessage());
                    }
                }
        );

        /* Add your Requests to the RequestQueue to execute */
        mRequestQueue.add(req);
    }
}

您可以在github上找到完整的示例项目:

https://github.com/xomena-so/so44735477

希望这有帮助!