In my application im trying to prevet the user to be able to scroll "free" around the map activity , i want the display content to be lock in some specific coordinates but the difficult part is to concatenate this with the ability of the camera geolocalization(GPS) to follow around the user .
i can for example try to add a move camera to the onLocationChanged and this will lock the camera in the region that i want evry time the user move , but this is not what i want , i just want to reset the camera if the user scroll in a zone that i dont want him to see , if you are browsing the map of Washington i want the camera to reset if the user goes for example on baltimora .
LatLng Washington = new LatLng(38.9150303, -77.1655794);
public void onLocationChanged(Location location) {
LatLng me = new LatLng(location.getLatitude(),location.getLongitude());
//LOCK CAMERA
mMap.moveCamera(CameraUpdateFactory.newLatLng(Washington));
//Marker Position
if (null != currentMarker) {
currentMarker.remove();
}
currentMarker = mMap.addMarker(new MarkerOptions().position(me).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN)));
If you want the user to be able to move the map but restrict to a given area, the map offers you that option.
As mentioned here : Restricting the user's panning to a given area
private GoogleMap mMap;
// Create a LatLngBounds that includes the city of Adelaide in Australia.
private LatLngBounds ADELAIDE = new LatLngBounds(
new LatLng(-35.0, 138.58), new LatLng(-34.9, 138.61));
// Constrain the camera target to the Adelaide bounds.
mMap.setLatLngBoundsForCameraTarget(ADELAIDE);
Related
When I tap the screen, a marker gets added to the middle of a Mapbox map. The first marker shows up as it is supposed to. However as soon as I add a second marker, the markers show up grey.
Here is the code I use to create the symbol source and the symbol layer, as well as the onMapClickListener where the features of the symbol source get updated with the new marker. All this code is in the onStyleLoaded method.
//Create the symbol source
Drawable drawable = ResourcesCompat.getDrawable(getResources(), R.drawable.ic_map_marker_blue, null);
Bitmap marker = BitmapUtils.getBitmapFromDrawable(drawable);
style.addImage(BLUE_MARKER_IMAGE, marker);
GeoJsonSource geoJsonSourceSymbol = new GeoJsonSource(SYMBOL_SOURCE_ID);
style.addSource(geoJsonSourceSymbol);
//Create the symbol layer
symbolLayer = new SymbolLayer(SYMBOL_LAYER_ID, SYMBOL_SOURCE_ID);
symbolLayer.setProperties(iconImage(BLUE_MARKER_IMAGE), iconOffset(new Float[] {0f, -10f}));
style.addLayer(symbolLayer);
mapboxMap.addOnMapClickListener(new MapboxMap.OnMapClickListener() {
#Override
public boolean onMapClick(#NonNull LatLng point) {
final LatLng mapTargetLatLng = mapboxMap.getCameraPosition().target;
Point mapTarget = Point.fromLngLat(mapTargetLatLng.getLongitude(),mapTargetLatLng.getLatitude());
pointList.add(mapTarget);
featureList.add(Feature.fromGeometry(mapTarget));
if (style.getLayer(SYMBOL_LAYER_ID) != null) {
GeoJsonSource geoJsonSourceSymbol = style.getSourceAs(SYMBOL_SOURCE_ID);
if (geoJsonSourceSymbol != null) {
geoJsonSourceSymbol.setGeoJson(FeatureCollection.fromFeatures(featureList));
}
}
return true;
}
});
Is there something I'm doing wrong or is it not possible to dynamically add symbols using data-driven styling?
Are you using an emulator? The Mapbox team already knows of SymbolLayer rendering issues on emulated devices:
https://github.com/mapbox/mapbox-gl-native/issues/10829
https://github.com/mapbox/mapbox-plugins-android/issues/1082
I want to develop an app on google map that could notify me with some information set by the user when I am close to the exact location. So can I get a link for this that How can I get pop-ups when I am at the exact(user) location?
You'll first need to enable a location manager to start getting the user's current location. Then, every time the user's location updates, the location manager calls the onLocationChanged() method. Here, you would want to check the distance between the user's current location and the destination location. If they are within whatever distance you choose, then you can display your map marker. Here is a little example of how to do that:
#Override
public void onLocationChanged(Location location) {
float distanceInMeters = destLocation.distanceTo(location);
// Distance in miles
double distance_to_dest = (distanceInMeters/1609.344);
int distance_to_dest_int = (int)(distance_to_dest * 100);
distance_to_dest = ((double)distance_to_dest_int/100.00);
tvMilesToGo.setText(String.format("%.2f", distance_to_dest) + "mi");
// About 1/10th of a mile
if ((distanceInMeters > 149) && (distanceInMeters < 176)) {
// I played an alarm sound when close to the target destination
//if (alarmPlayer.isPlaying()) {
// alarmPlayer.stop();
//}
//alarmPlayer.start();
Marker marker = mMap.addMarker(new MarkerOptions()
.position(new LatLng(destLocation.getLatitude(), destLocation.getLongitude()))
.title(“Arrived”)
.snippet(“You have arrived at your destination!”)
.icon(red_descriptor));
Marker.showInfoWindow;
}
}
Note, in your case, you would probably only ever want to add a marker once, so, you would probably want to set a flag such as markerIsVisible = true once you add it to the map, and then check before adding the marker if (markerIsVisible == false) {add the marker, markerIsVisible = true}
I'm working on a project with google maps and I want to update the camera and camera zoom to the location of the user but only once (when the app is running) why only once? because I want the user to be able to move and drag around the map without updating the camera every 5 or "n" seconds.
I get the users position in the method onLocationChanged() and then I update the camera, but this is updating the camera every 5 seconds (my interval) and i is not what I want. I just want to update it the first time when the map is opened.
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "OnLocationChanged"+String.valueOf(location.getLatitude())
+ "longitude" + String.valueOf(location.getLongitude()));
eraseMarkers();
if (mMap != null) {
LatLng newLatLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(newLatLng,CAMARA_ZOOM));
I appreciate your help
I have an ArrayList of LatLng, and in a forloop of onMapReady(GoogleMap googleMap) I would like to animate moving from location to another in order.
I tried doing this in a for loop:
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(currLatLng,10), 1000, null);
and the animation happens only at the last location.
How would I go about doing so? Should I use the last parameter of animateCamera() method? (Cancellable Callback)
My instinct was correct.
The last parameter in animateCamera is a CancellableCallback() interface.
What I did is made a method called animateToLocationAtIndex(int index)
And then called:
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 10), 2000, new GoogleMap.CancelableCallback() {
#Override
public void onFinish() {
// Placing a marker on the position after animated
Marker marker = mMap.addMarker(markerOptions);
animateLocationMovement(i+1);
}
This animates the locations as I wanted, although I ran into another issue where the map at the next location isn't loaded so it may seem like the animation is laggy.
I'm trying to create an app for android with little experience programming. I want to use a phones gps to determine a place on google maps then cause an action to happen. The action would be based on the location and I'd also like to have the user designate locations to cause an action.
If there are any resources or websites you can point me to I would really appreciate it.
I'm currently only using android studio, is there anything else I need?
first, you need the current user location. You can follow the steps offered here to obtain it. The locationmanager provides a method onLocationChanged(Location loc) which then is triggered automatically when the location changes. You can implement your "actions" here. Im not quite sure if I have understood what the designation of locations by the user would have to trigger.
If you want to trigger a specific "action", you can implement the method onMapClicked(Location loc) by setting an onMapClickListener to your map.
Depending on how your "predefined places" are built, you have different possibilities.
1) Are those places points? --> you can calculate the euclidian (or spherical) distances, and related to that distance decide if you want to trigger something or not.
2) are those places 2d rectangles? --> use LatLngBounds and its contains(LatLng point) method to decide if the userlocation or user-designated-location is inside
3) are those places any polygons? here is a good example on how to create such a place. there is also a contains() method.
4) Are your places not predefined? We need more information on what you want to do in this case.
edit based upon ur comment :
so you there are 2 things your app should do:
1) do some action (just like popping up a message), when the user is entering a "place" or comming near to a "place"
2) give the user the possibily to create such a place by himself.
secondary can be done by adding a onMapClickListener to your map.
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
// latLng is the lcoation, tapped by the user on the map. lets save it
chosen_location = new LatLng(latLng.latitude, latLng.longitude);
}
});
}
This will save the single points, tabbed by a user on a map. If you wanna go further later for polygons, you can add this point to an ArrayList of points. However, you probably want the user to add more information about that point. Make use of EditText to let the user e.g. enter a description of that point (or later polygon), and finally, when clicking a button to "save that entered place", you can add it to an ArrayList. You probably also gonna have a server-backend in order to update and retrieve a list of places created by multiple people from anywhere.
but for now, lets go on and check if the user came nearTo such a point or entered such a polygon:
LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 35000, 10, new LocationListener() {
#Override
public void onLocationChanged(Location location) {
// the users location changed (e.g. he moved some meters)
current_location = new LatLng(location.getLatitude(), location.getLongitude());
// somehow get all the places ( i guess a server backend is recommended )
// for now, lets say all the places are already obtained into an Arraylist called places:
ArrayList<LatLng> places = new ArrayList<LatLng>;
// Go check for each of the places, if the users current location is near to such a point
for (LatLng place : places) {
if (distance(place,current_location)<100) {
LatLng near_place = place;
// here we are! near_place is near the users current location, lets do some action
Log.d("app","Users location (" + current_location.latitude +","+current_location.longitude+") is near to a place with coordinates "+near_place.latitude+","+near_place.longitude+").");
}
}
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
});
}
and here is a method to calculate (spherical) distance in meters between to LatLng objects:
/**
* method calculate distance between two LatLng points in meter
*/
public float distance(double lat_a, double lng_a, double lat_b, double lng_b) {
double earthRadius = 3958.75;
double latDiff = Math.toRadians(lat_b - lat_a);
double lngDiff = Math.toRadians(lng_b - lng_a);
double a = Math.sin(latDiff / 2) * Math.sin(latDiff / 2) +
Math.cos(Math.toRadians(lat_a)) * Math.cos(Math.toRadians(lat_b)) *
Math.sin(lngDiff / 2) * Math.sin(lngDiff / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = earthRadius * c;
int meterConversion = 1609;
return new Double(distance * meterConversion).floatValue();
}