zoom over specific route google map

前端 未结 9 1083
感动是毒
感动是毒 2021-02-05 11:23

I have a list of random latitude and longitude points and I am drawing a route between them. My question is how to bound this route within google map I made below utili

相关标签:
9条回答
  • 2021-02-05 11:51

    Try implementing this way

    /**
     * Zooms a Route (given a List of LalLng) at the greatest possible zoom level.
     *
     * @param googleMap: instance of GoogleMap
     * @param lstLatLngRoute: list of LatLng forming Route
     */
    public void zoomRoute(GoogleMap googleMap, List<LatLng> lstLatLngRoute) {
    
        if (googleMap == null || lstLatLngRoute == null || lstLatLngRoute.isEmpty()) return;
    
        LatLngBounds.Builder boundsBuilder = new LatLngBounds.Builder();
        for (LatLng latLngPoint : lstLatLngRoute)
            boundsBuilder.include(latLngPoint);
    
        int routePadding = 100;
        LatLngBounds latLngBounds = boundsBuilder.build();
    
        googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(latLngBounds, routePadding));
    }
    

    UPDATE

    After looking at the image, there are layouts above map. So it would require you to set Variable Padding. You can do it as

    googleMap.setPadding(left, top, right, bottom);
    

    Note: While setting variable padding, you can initialize routePadding = 0; In your case, approximations are: left = right = 10, bottom=100, top=200. Once set, you can calibrate'em as per your requirement.

    Recommendation: You can calculate the height of those (top and bottom) layouts in pixels and then set padding accordingly.

    0 讨论(0)
  • 2021-02-05 11:51

    The reason, why zooming in is not working might be because map has not been inflated yet at the time of calling the method:

    moveCamera(com.google.android.gms.maps.CameraUpdate)

    Try adding ViewTreeObserver.OnGlobalLayoutListener to the map:

    ViewTreeObserver vto = googleMap.getViewTreeObserver();
    ViewTreeObserver.OnGlobalLayoutListener globalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                googleMap.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                googleMap.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
            googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(), 10));
        }
    };
    vto.addOnGlobalLayoutListener(globalLayoutListener);
    

    If the method above does not work GoogleMap has it's own listener for layout, you might use that:

    googleMap.setOnCameraChangeListener(new OnCameraChangeListener() {
    
        @Override
        public void onCameraChange(CameraPosition arg0) {
            googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(), 10));
            googleMap.setOnCameraChangeListener(null);
        }
    });
    

    However, as of play-services-maps 9.4.0 version of the API the method above is deprecated. Use one of:

    • GoogleMap.OnCameraMoveStartedListener

    • GoogleMap.OnCameraMoveListener

    • GoogleMap.OnCameraIdleListener

    0 讨论(0)
  • 2021-02-05 11:51

    How I did it.

    Android - plotting gps coordinate on custom map

    Yes you can draw points that aren't on the visible map. Get around this by setting up a LatLngBounds. Then display the map for the LatLngBounds. You can also move the map to display the LatLngBounds. There's nothing tricky here no tangents or slopes or hyperbolic curvature of the earth. All that's taken care of by the point which is in degrees so don't over think your solution. If you turn the map the points will turn with it. So add your points to the map find the bounds and tilt the camera. Tilt the camera back and all the points will still be on screen! This will get you started with the all the points on the screen.

    Same as the samples get a reference to a google map.

    private void setUpMapIfNeeded() {
    // Do a null check to confirm that we have not already instantiated the
    // map.
    
    if (mMap == null) {
        // Try to obtain the map from the SupportMapFragment.
        // mMap = mMapFragment.getMap();
        // // Check if we were successful in obtaining the map.
    
        // Try to obtain the map from the SupportMapFragment.
        mMap = ((SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map)).getMap();
        // use the settings maptype
    
        // Check if we were successful in obtaining the map.
        if (mMap != null) {
            setUpMap();
        }
    }
    }
    

    Let's get started finding the boundry of the map.

    import com.google.android.gms.maps.model.LatLng;
    import com.google.android.gms.maps.model.LatLngBounds;
    A field for LatLngBounds and a LatLngBounds.Builder
    
    private LatLngBounds bounds;
    private LatLngBounds.Builder myLatLngBuilder;
    initialize the LatLngBounds.Builder
    
    myLatLngBuilder = new LatLngBounds.Builder();
    for each point on your map.
    
    LatLng myLatLng = new LatLng(latitude, longitude);
    myLatLngBuilder.include(myLatLng);
    Then when your finished adding points build your boundary.
    
    bounds = myLatLngBuilder.build();
    Now I have the bounds of all the points on my map and I can display just that area of the map. This code I lifted from the map samples.
    
    final View mapView = getSupportFragmentManager().findFragmentById(
                R.id.map).getView();
        if (mapView.getViewTreeObserver().isAlive()) {
            mapView.getViewTreeObserver().addOnGlobalLayoutListener(
                    new OnGlobalLayoutListener() {
                        @SuppressWarnings("deprecation")
                        // We use the new method when supported
                        @SuppressLint("NewApi")
                        // We check which build version we are using.
                        @Override
                        public void onGlobalLayout() {
                            if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                                mapView.getViewTreeObserver()
                                        .removeGlobalOnLayoutListener(this);
                            } else {
                                mapView.getViewTreeObserver()
                                        .removeOnGlobalLayoutListener(this);
                            }
                            mMap.moveCamera(CameraUpdateFactory
                                    .newLatLngBounds(bounds, 50));
                        }
                    });
        }
    
    0 讨论(0)
  • 2021-02-05 11:53

    I implemented a similar solution to @rishabh-dutt-sharma with a couple of twists:

    • First of all, before zooming check if the points are already inside the view. If they are, do not change it. This means less unneeded changes in the UI for the user.
    • Second, a special case is when there is just one point. This is useful when showing a list of markers, and maybe is not needed in your particular case. The reason of why is this useful is because in the case of single point, the zoom usually is increased to the maximum, and usually this is too much.

    This is the code (adapted from my original code, I hope there are no typos):

        public void zoomRoute(GoogleMap googleMap, List<LatLng> lstLatLngRoute) {
    
            if (googleMap == null || lstLatLngRoute == null || lstLatLngRoute.isEmpty()) return;
    
            LatLngBounds currentLatLongBounds =
                    googleMap.getProjection().getVisibleRegion().latLngBounds;
            boolean updateBounds = false;
    
            for (LatLng latLng : lstLatLngRoute) {
                if (!currentLatLongBounds.contains(latLng)) {
                    updateBounds = true;
                }
            }
    
            if (updateBounds) {
    
                CameraUpdate cameraUpdate;
    
                if (lstLatLngRoute.size() == 1) {
    
                    LatLng latLng = lstLatLngRoute.iterator().next();
                    cameraUpdate = CameraUpdateFactory.newLatLng(latLng);
    
                } else {
    
                    LatLngBounds.Builder builder = LatLngBounds.builder();
                    for (LatLng latLng : lstLatLngRoute) {
                        builder.include(latLng);
                    }
                    LatLngBounds latLongBounds = builder.build();
    
                    cameraUpdate =
                            CameraUpdateFactory.newLatLngBounds(latLongBounds, MAP_ZOOM_PADDING);
    
                }
    
                try {
                    googleMap.animateCamera(cameraUpdate, MAP_CAMERA_ANIMATION_DURATION_IN_MILLIS,
                            new GoogleMap.CancelableCallback() {
                                @Override
                                public void onFinish() {
                                }
    
                                @Override
                                public void onCancel() {
                                }
                            });
                } catch (IllegalStateException ex) {
                    // Ignore it. We're just being a bit lazy, as this exception only happens if
                    // we try to animate the camera before the map has a size
                }
            }
        }
    
    0 讨论(0)
  • 2021-02-05 11:56

    Probably This would be most simple solution for above mentioned problem, It worked for me very well.

    Add all the waypoints to the target under GoogleMapOptions:camera, then it will automatically set the zoom and center the map with respect to Polyline( given Route).

    loadMap() {
    
    let mapOptions: GoogleMapOptions = {
      camera: {
        target: this.wayPoints,
        zoom: 25,
        tilt: 30
      }
    };
    
    this.map = GoogleMaps.create('map_canvas', mapOptions);
    this.map.one(GoogleMapsEvent.MAP_READY)
      .then(() => {
        console.log('Map is ready!');
    
    
       this.map.addPolyline({
          points:this.wayPoints,
          color:'#586bff',
          width: 8,
          geodesic:true,
        });
    });
    }
    

    The waypoints( this.wayPoints ) should be in this format:

    [{lat: 52.33806, lng: 8.61179},
    {lat: 52.33812, lng: 8.61185},
    {lat: 52.33812, lng: 8.61186},
    {lat: 52.33812, lng: 8.61188}]
    
    0 讨论(0)
  • 2021-02-05 12:00

    You need to include all the points that form the polyline into your mapBounds object.

    Also, you are updating the camera using animateCamera and then you are moving it using moveCamera. This second camera update overrides the first one. Just remove the line

    googleMap.moveCamera(CameraUpdateFactory.zoomOut());
    

    This line is also innecesary (you don't need to move and animate the camera, just one of them):

    googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(), 10));
    

    If you need to zoom out a bit your map you can play with the padding parameter of the CameraUpdateFactory.newLatLngBounds method.

    0 讨论(0)
提交回复
热议问题