well, i'm developing a geolocation app in Android. On first run we center the map at the current location, then the user can zoom and pan freedomly, but we have a button that animates the map and centers it back to the actual position.
The problem is that this just happens when the map is static: if the user scrolls the map and leaves it scrolling by inertia, this button won't work until the animation is stopped.
Here's the code.
mapView.getController().stopAnimation(false); //this aint working as expected
mapView.getController().animateTo(myLocationOverlay.getMyLocation());
Thanks.
This works for me:
public void centerCurrentClickHandler(View v) {
if (hasCurrentPosition) {
GeoPoint point = new GeoPoint(currentLatitudeE6, currentLongitudeE6);
mapController.animateTo(point);
}
}
public void centerFlagClickHandler(View v) {
if (hasPushpinPosition) {
GeoPoint point = new GeoPoint(pushpinLatitudeE6, pushpinLongitudeE6);
mapController.animateTo(point);
}
}
Related
I'm writing an application on android that will show a map from google maps. When I start the app, the map is centered on the current location. When I use animateCamera, I can see the zoom-in animation from the whole world until it focuses on current location.
The problem is that I need to touch the map to get the map to display at the zoom level I expected.
Here is what I get before I touch the screen :
Before touch
Here is what I get after having touch the screen :
After touch
If I touch the screen, the image will remain fine, until I drive a few hundred meters and then it's again unuseable. Sometimes the image appears, but it's only 1 or 2 times per 10km.
Here is how I move the camera inside LocationListener::onLocationChanged :
float zoom = 19.0f;
LatLng target = new LatLng(location.getLatitude(), location.getLongitude());
// moving car marker
m_locationMarkerG.setPosition(target);
m_locationMarkerG.setRotation(location.getBearing());
// tilting camera depending on speed
float tilt = Math.min(90, location.getSpeed()*10);
m_mapViewG.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder().zoom(zoom).bearing(location.getBearing()).
target(target).tilt(tilt).build()));
What could I try to solve this ?
Thanks
Found solution :
animateCamera MUST be called from the main looper. The LocationListener is called from another thread (sensor's thread).
So the code become :
final float zoom = 19.0f;
final LatLng target = new LatLng(location.getLatitude(), location.getLongitude());
// tilting camera depending on speed
final float tilt = Math.min(90, location.getSpeed()*10);
m_handler.post(new Runnable() {
public void run() {
// moving car marker
m_locationMarkerG.setPosition(target);
m_locationMarkerG.setRotation(location.getBearing());
// moving camera
m_mapViewG.animateCamera(CameraUpdateFactory.newCameraPosition(CameraPosition.builder().zoom(zoom).bearing(location.getBearing()).target(target).tilt(tilt).build()));
}
});
The google map marker can be dragged around the screen so I want to know if there's a way to trigger an event when the marker is dropped at a certain location on the screen, say, bottom left.
After layout created and map initialized add the following code in onCreate();
View mapView = getSupportFragmentManager().findFragmentById(R.id.map).getView();
if (mapView.getViewTreeObserver().isAlive()) {
mapView.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
mapView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
map.moveCamera(CameraUpdateFactory.newLatLngZoom(CENTER, 15));
Point markerScreenPosition = map.getProjection().toScreenLocation(marker.getPosition());
int x = markerScreenPosition.getX();
int y = markerScreenPosition.getY();
if(x == yourValue && y == yourValue){
//your trigger code goes here
}
}
});
}
I think markers are not automatically dropped. they are handled by your code. for example you can add a marker on map click or on map long click. get that event and try fixing
In our application, a lot of markers are drawn in different locations and in certain cases at a certain zoom level, markers overlap each other. So when I click on the marker, I expect the top marker's onMarkerClick to be fired but instead it is fired for the last hidden marker i-e the last marker, with no markers behind it.
What do you suggest I do? Also, I have no info windows, therefore I return true from onMarkerClick method.
I found the solution here: https://github.com/googlemaps/android-maps-utils/issues/26
mGoogleMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter()
{
#Override
public View getInfoWindow(Marker marker)
{
// Empty info window.
return new View(getApplicationContext());
}
#Override
public View getInfoContents(Marker marker)
{
return null;
}
});
Identify the size of your maker relative to the overall screen (e.g. 10%). Define this as a float called IMAGE_SIZE_RATIO
Maintain List markers as you add markers to your map. In your OnMarkerClickListener onMarkerClick method iterate through your other markers and compare distance between the markers relative to the current visible map dimensions and the marker size. As in the following example code:
static final float IMAGE_SIZE_RATIO = .15f; //define how big your marker is relative to the total screen
private void setupListeners() {
getMap().setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
LatLngBounds b = getMap().getProjection().getVisibleRegion().latLngBounds;
Float distance = distanceBetweenPoints(b.northeast, b.southwest) * IMAGE_SIZE_RATIO;
for (Marker m : makers ) {
if (marker.equals(m) ) { continue; } //don't compare the same one
if (distanceBetweenPoint(m.getPosition(), marker.getPosition()) {
/*Note do onMarkerClick this as an Aynch task and continue along
if also want to fire off against the main object.
*/
return onMarkerClick(m);
}
}
// do the operation you want on the actual marker.
}
....(remainder of listener)...
}
}
protected Float getDistanceInMeters(LatLng a, LatLng b) {
Location l1 = new Location("");
Location l2 = new Location("");
l1.setLatitude(a.latitude);
l1.setLongitude(a.longitude);
l2.setLatitude(b.latitude);
l2.setLongitude(b.longitude);
return l1.distanceTo(l2)
}
I'm trying to develop a layout that shows a Google Map with a route drawn on a Overlay layer associated with this map. I want this mapView to be a small static map that shows, as a thumbnail, the main route the user followed, and then if the user clicks on it, an intent takes you to a different activity displaying the map in full screen with the route and all the zoom functionalities.
The thing is that although I override the onTap method of the Overlay setting there the intent to the new activity, it only works if I set the MapView as setEnabled(true), but if I do so, then the thumbnail map can be dragged and moved by the user.
I'm sorry if it is not clear enough, but I don't know how to explain it better.
Thanks in advance
This is my customized class which extends Overlay and overrides the onTap method:
class MapOverlay extends Overlay {
#Override
public boolean onTap(GeoPoint p, MapView mapView) {
Intent i = new Intent(getApplicationContext(),
RouteMapActivity.class);
startActivity(i);
return false;
};
And this is my onCreate method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detailrun_activity);
map = (MapView) findViewById(R.id.mvMain);
map.setEnabled(true);
map.setClickable(true);
MapOverlay mapOverlay = new MapOverlay();
List<Overlay> listOfOverlays = map.getOverlays();
projection = map.getProjection();
listOfOverlays.clear();
listOfOverlays.add(mapOverlay);
double lat = 28.063119 * 1E6, longi = -82.41128 * 1E6;
GeoPoint point = new GeoPoint((int) lat, (int) longi);
MapController myMapController = map.getController();
myMapController.setCenter(point);
}
For now I'm only drawing a straight line between two GeoPoints, and I don't get any logcat errors.
The map with the route is indeed drawn, and the overrided onTap method works, but it seems it only recognizes the tap if my mapView is defined as enabled and clickable, but if I do so, then the user can also move and drag the map as long as he holds pressing the screen.
you can get static google map image as per your location by this link. that you can display in imageview and click on that you can target new activity which have MapView.. i think it may be a good option for you.
I have been working on an offline map using OSMdroid
I have map tiles of two zoom levels namely 12 and 15
Now the usual double tap zooms the mapview by 1 level
What i m trying to do is to setZoomLevel() as 15 after the user double taps on the map,
Is it possible?
I tried using onGestureListener , but somehow it is not working
Any hint or clues in that direction or sample codes would be a big help , Thanks
I had a similar requirement with the Osmdroid MapView, in that I didn't want it to do the 'centre on the double tapped location and zoom in' default functionality. I wanted it to pop up a Toast. In my case I had an overlay on top of the MapView, so I just had the overlay consume the double tap in its onDoubleTap method. For your purposes you could just add an overlay which draws nothing but has its own double tap functionality.
So at the end of your onCreate, you could add the overlay. This little app seems to demonstrate what you want - (you'll need to add conditional code for checking zoom level and other tinkering):
public class OsmdroidDemoMap extends Activity {
private MapView mMapView;
private MapController mMapController;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.osm_main);
mMapView = (MapView) findViewById(R.id.mapview);
mMapView.setTileSource(TileSourceFactory.MAPNIK);
mMapView.setBuiltInZoomControls(true);
mMapController = mMapView.getController();
mMapController.setZoom(13);
GeoPoint gPt = new GeoPoint(51500000, -150000);
mMapController.setCenter(gPt);
DummyOverlay dumOverlay = new DummyOverlay(this);
List<Overlay> listOfOverlays = mMapView.getOverlays();
listOfOverlays.clear();
listOfOverlays.add(dumOverlay);
}
public class DummyOverlay extends org.osmdroid.views.overlay.Overlay {
public DummyOverlay(Context ctx) {
super(ctx); // TODO Auto-generated constructor stub
}
#Override
protected void draw(Canvas c, MapView osmv, boolean shadow) {}
#Override
public boolean onDoubleTap(MotionEvent e, MapView mapView) {
// This stops the 'jump to, and zoom in' of the default behaviour
int zoomLevel = mMapView.getZoomLevel();
mMapController.setZoom(zoomLevel + 3);
return true;// This stops the double tap being passed on to the mapview
}
}
If you need to manage the double-tap in an MapView, i suggest you to check this thread:
android maps: How to Long Click a Map?
You can see my answer and how i adapted mapview-overlay-manager.
you can override the zoom control with its event, for that you need to define into the xml layout or you get the zoom control from the mapview
ZoomControls zoomControls = (ZoomControls)findViewById(R.id.zoomControl);
View zoomOut = zoomControls.getChildAt(0);
zoomOut.setBackgroundDrawable(getResources().getDrawable(R.drawable.zoom_out_icon));
zoomOut.setPadding(5, 5, 5, 5);
View zoomIn = zoomControls.getChildAt(1);
zoomIn.setBackgroundDrawable(getResources().getDrawable(R.drawable.zoom_in_icon));
zoomIn.setPadding(5, 5, 5, 5);
zoomControls.setOnZoomInClickListener(new View.OnClickListener() {
public void onClick(View v) {
mc.zoomIn();
mapView.invalidate();
}
});
zoomControls.setOnZoomOutClickListener(new View.OnClickListener() {
public void onClick(View v) {
mc.zoomOut();
mapView.invalidate();
}
});
now you can implement your own zoom control
In the latest OSMdroid library 4.0 has inbuilt automatic double tap zoom in. But nothing is better than having a zoom control.
you can use just add below line
mMapView.setMultiTouchControls(true);