【问题标题】:Picking the right Zoom level for different cities in GoogleMaps在 Google 地图中为不同城市选择合适的缩放级别
【发布时间】:2017-06-24 10:37:10
【问题描述】:

我有一个实现 OnMapReadyCallback 的活动来显示一些标记。 在打开地图之前,我提供了一个目标城市,我想通过以下方式在地图上仔细查看:

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

这里的主要问题是缩放级别只是一个任意数字,它适用于某些城市而对其他城市不好(放大太多,放大不够)。 我想要实现的是根据城市动态确定缩放级别,就像谷歌地图一样。

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

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

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

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

【问题讨论】:

  • 我认为一个好的长期解决方案是使用包含城市和每个城市所需的缩放级别的属性文件。请记住,您想要的每个城市的缩放级别甚至可能会随着时间而改变。
  • 是的,我也这么认为,但我无法控制数据库中的每个城市。我的意思是用户可以将标记添加到我没有列出的一个非常小的城市,我读到 JS API 提供了一些有趣的功能来解决这个问题,但我的 Javascript 水平可以说是平庸的。跨度>
  • 赞成。我现在也在使用 Android 上的地图。但我只处理一小部分城市,所以我可以只用硬编码一个值就可以了。

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


【解决方案1】:

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

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

从坐标获取城市的反向地理编码请求示例如下 https://maps.googleapis.com/maps/api/geocode/json?latlng=47.376887%2C8.541694&amp;result_type=locality&amp;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

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多