zoom over specific route google map

2019-03-25 00:14发布

enter image description herebelow is screen shot @antonio what i get after removing line

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 utility method

public static void drawRouteIntoMap(final List<? extends MapHelper> position, final GoogleMap googleMap) {
    /*List<MapHelper> position = new ArrayList<MapHelper>();
    for (int i = lastPosition; i < maps.size(); i++) {
        position.add(maps.get(i));
    }*/
    if (position.size() > 0 && Validator.isNotNull(googleMap)) {
        googleMap.clear();
        List<PolylineOptions> polylineOptionses = new ArrayList<PolylineOptions>();
        PolylineOptions option = null;
        Boolean lastPause = null;
        for (MapHelper map : position) {
            if (map.isPause()) {
                if (Validator.isNull(lastPause) || !lastPause) {
                    option = new PolylineOptions().width(5).color(Color.rgb(255, 0, 155)).geodesic(true);
                    polylineOptionses.add(option);
                }
                option.add(new LatLng(map.getLatitude(), map.getLongitude()));
            } else {
                if (Validator.isNull(lastPause) || lastPause) {
                    option = new PolylineOptions().width(5).color(Color.rgb(0, 179, 253)).geodesic(true);
                    polylineOptionses.add(option);
                }
                option.add(new LatLng(map.getLatitude(), map.getLongitude()));
            }
            lastPause = map.isPause();
        }
        for (PolylineOptions options : polylineOptionses) {
            googleMap.addPolyline(options);
        }
        if(Validator.isNotNull(option)){
            //List<LatLng> points = option.getPoints();
            final LatLngBounds.Builder mapBounds = new LatLngBounds.Builder();

            googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
                @Override
                public void onMapLoaded() {
                    LatLng startPoint = new LatLng(position.get(0).getLatitude(), position.get(0).getLongitude());
                    googleMap.addMarker(new MarkerOptions().position(startPoint).title("start").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
                    mapBounds.include(startPoint);
                    LatLng endPoint = new LatLng(position.get(position.size() - 1).getLatitude(), position.get(position.size() - 1).getLongitude());
                    mapBounds.include(endPoint);
                    googleMap.addMarker(new MarkerOptions().position(endPoint).title("finish").icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
                    googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(), 10));
                   /* googleMap.animateCamera(CameraUpdateFactory.newLatLngBounds(mapBounds.build(), 10));
                    googleMap.moveCamera(CameraUpdateFactory.zoomOut());*/

                }
            });
        }

    }
}

here last pause is boolean indicating whether it is paused point for indicating red color polyline.

but it is not working.Any help is appreciated.

9条回答
Anthone
2楼-- · 2019-03-25 00:47

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
            }
        }
    }
查看更多
Rolldiameter
3楼-- · 2019-03-25 00:47

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}]
查看更多
一夜七次
4楼-- · 2019-03-25 00:55

you can do one thing, find out the distance between 2 latitude and longitude and make check over distance that you got.See,how it work . It's a trick it might useful for you.

googleMap.moveCamera(CameraUpdateFactory.newLatLng(reachLocationLatLng));
if (dist > 2 && dist <= 5) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(13.0f));
mapZoomLevel = 12;
} else if (dist > 5 && dist <= 10) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(12.0f));
mapZoomLevel = 11;
} else if (dist > 10 && dist <= 20) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(11.0f));
mapZoomLevel = 11;
} else if (dist > 20 && dist <= 40) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(10.0f));
mapZoomLevel = 10;
} else if (dist > 40 && dist < 100) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(9.0f));
mapZoomLevel = 9;
} else if (dist > 100 && dist < 200) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(8.0f));
mapZoomLevel = 8;
} else if (dist > 200 && dist < 400) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(7.0f));
mapZoomLevel = 7;
} else if (dist > 400 && dist < 700) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(6.0f));
mapZoomLevel = 7;
} else if (dist > 700 && dist < 1000) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(5.0f));
mapZoomLevel = 6;
} else if (dist > 1000) {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(4.0f));
mapZoomLevel = 5;
} else {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(14.0f));
mapZoomLevel = 14;
}

Thanks hope this will help you.

查看更多
一纸荒年 Trace。
5楼-- · 2019-03-25 00:57

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.

查看更多
相关推荐>>
6楼-- · 2019-03-25 01:05
 googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(endPoint,zoomLevel));

Try it if it helps you

查看更多
迷人小祖宗
7楼-- · 2019-03-25 01:08

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.

查看更多
登录 后发表回答